From d17a9072d45f4b89b717ce5281ecb7b21048225a Mon Sep 17 00:00:00 2001 From: Ian Little Date: Fri, 29 Mar 2019 10:42:38 -0400 Subject: [PATCH 01/39] Update Handle server version. --- dspace-api/pom.xml | 4 ++-- .../java/org/dspace/handle/HandlePlugin.java | 2 +- dspace/bin/make-handle-config | 17 +++++++++-------- pom.xml | 10 +++++----- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 1a7326fa75..5d70c5c329 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -452,11 +452,11 @@ org.bouncycastle - bcprov-jdk15 + bcprov-jdk15on org.bouncycastle - bcmail-jdk15 + bcmail-jdk15on org.apache.poi diff --git a/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java b/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java index 9e8d04faf2..9e43d1f9da 100644 --- a/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java +++ b/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java @@ -20,7 +20,7 @@ import net.handle.hdllib.HandleStorage; import net.handle.hdllib.HandleValue; import net.handle.hdllib.ScanCallback; import net.handle.hdllib.Util; -import net.handle.util.StreamTable; +import net.cnri.util.StreamTable; import org.apache.logging.log4j.Logger; import org.dspace.core.Context; import org.dspace.handle.factory.HandleServiceFactory; diff --git a/dspace/bin/make-handle-config b/dspace/bin/make-handle-config index 543ad8b50e..51c75289ce 100755 --- a/dspace/bin/make-handle-config +++ b/dspace/bin/make-handle-config @@ -26,13 +26,13 @@ tempfile=/tmp/handleconfig$$ contactemail=`$BINDIR/dspace dsprop --property mail.admin` # Write the options to a file we can pipe into the setup tool -echo "1" >$tempfile # 1 = non-caching server, 2 = caching server -echo "" >>$tempfile # Primary server? Default = y (n = mirror server) +echo "" >$tempfile # Primary server? Default = y (n = mirror server) +echo "" >>$tempfile # Dual-stack (IPv4 and IPv6)? (default=n) echo $dshostip >>$tempfile # IP address +echo "" >>$tempfile # DBind address (default=same as IP) echo "" >>$tempfile # Port to listen to (default=2641) echo "" >>$tempfile # Port for HTTP i/f to listen to (default=8000) -echo "" >>$tempfile # Log all accesses? ("y" or "n", default=n) -echo "" >>$tempfile # Rotate logs? (default=No) +echo "n" >>$tempfile # Log all accesses? ("y" or "n", default=y) echo "" >>$tempfile # Version/serial no. of site (default=1) echo $dsname Handle Server >>$tempfile # Server description echo $dsname >>$tempfile # Server descriptive name @@ -53,16 +53,17 @@ rm -f $tempfile # Now update server configuration (config.dct) with our handle prefix and the # DSpace Handle plugin -sed 's/YOUR_NAMING_AUTHORITY/'$handle'/' <$handledir/config.dct >$tempfile +sed 's/YOUR_PREFIX/'$handle'/' <$handledir/config.dct >$tempfile # Remove original config file - will replace rm -f $handledir/config.dct -# Insert our HandlePlugin - this awk script inserts these lines in the -# server_config section: +# Insert our HandlePlugin and turn off transaction queue. +# This awk script inserts these lines in the server_config section: # "storage_type" = "CUSTOM" # "storage_class" = "org.dspace.handle.HandlePlugin" -awk '/.*/ {print $0} /"server_config" = {/ {printf "\"storage_type\" = \"CUSTOM\"\n\"storage_class\" = \"org.dspace.handle.HandlePlugin\"\n\n",$0}' <$tempfile >$handledir/config.dct +# "enable_txn_queue" = "n" +awk '/.*/ {print $0} /"server_config" = {/ {printf "\"storage_type\" = \"CUSTOM\"\n\"storage_class\" = \"org.dspace.handle.HandlePlugin\"\n\"enable_txn_queue\" = \"no\"\n\n",$0}' <$tempfile >$handledir/config.dct #sed 's/"server_config" = {/"server_config" = {\n"storage_type" = "CUSTOM"\n"storage_class" = "org.dspace.handle.HandlePlugin"/' <$tempfile >$handledir/config.dct diff --git a/pom.xml b/pom.xml index a06a94dfa6..0e3e3060cf 100644 --- a/pom.xml +++ b/pom.xml @@ -1126,7 +1126,7 @@ org.dspace handle - 6.2 + 9.1.0 org.dspace @@ -1289,13 +1289,13 @@ org.bouncycastle - bcprov-jdk15 - 1.46 + bcprov-jdk15on + 1.59 org.bouncycastle - bcmail-jdk15 - 1.46 + bcmail-jdk15on + 1.59 org.apache.poi From f845e5fbcdb215d7e5802ec9c0c9d73764987a8f Mon Sep 17 00:00:00 2001 From: Ian Little Date: Fri, 29 Mar 2019 14:47:54 -0400 Subject: [PATCH 02/39] Include optional handle dependency that is needed for running the server. --- dspace-api/pom.xml | 10 ++++++++++ pom.xml | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 5d70c5c329..c561459d1f 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -335,6 +335,16 @@ org.dspace handle + + org.eclipse.jetty.aggregate + jetty-all + + + javax.servlet + org.eclipse.jetty.orbit + + + org.dspace jargon diff --git a/pom.xml b/pom.xml index 0e3e3060cf..59ec40c6aa 100644 --- a/pom.xml +++ b/pom.xml @@ -1128,6 +1128,17 @@ handle 9.1.0 + + org.eclipse.jetty.aggregate + jetty-all + 8.1.22.v20160922 + + + javax.servlet + org.eclipse.jetty.orbit + + + org.dspace jargon From d2f8db798ff2d0d45ad9985030601bb7cf01d4d7 Mon Sep 17 00:00:00 2001 From: Ian Little Date: Fri, 29 Mar 2019 14:48:21 -0400 Subject: [PATCH 03/39] Fix hostip issue in make-handle-config script. --- dspace/bin/make-handle-config | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dspace/bin/make-handle-config b/dspace/bin/make-handle-config index 51c75289ce..00daf3c29b 100755 --- a/dspace/bin/make-handle-config +++ b/dspace/bin/make-handle-config @@ -19,6 +19,10 @@ echo "Writing simple Handle server configuration" # Read parameters from DSpace config dshostname=`$BINDIR/dspace dsprop --property dspace.hostname` dshostip=`host $dshostname | awk '/has address/ { print $4; exit }'` +if [ "$dshostip" = "127.0.0.1" ]; then + # Just use default. SimpleSetup will fail when trying to bind to localhost addresses. + dshostip="" +fi dsname=`$BINDIR/dspace dsprop --property dspace.name` handle=`$BINDIR/dspace dsprop --property handle.prefix` handledir=`$BINDIR/dspace dsprop --property handle.dir` @@ -46,7 +50,7 @@ echo "n" >>$tempfile # Do not encrypt admin private key # OR do not overwrite old admin private key # Now run Handle server config tool, and pipe our config in -$BINDIR/dspace dsrun net.handle.server.SimpleSetup $handledir < $tempfile >/dev/null +$BINDIR/dspace dsrun net.handle.server.SimpleSetup $handledir < $tempfile >/dev/null 2>&1 # Remove temp file rm -f $tempfile From 0065bd49500bb9cb8591c3cfe2d976788c6cd64a Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 16 Apr 2019 12:10:49 -0500 Subject: [PATCH 04/39] Update version of Handle dependency --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 59ec40c6aa..0f06e54ec3 100644 --- a/pom.xml +++ b/pom.xml @@ -1126,7 +1126,7 @@ org.dspace handle - 9.1.0 + 9.1.0.v20190416 org.eclipse.jetty.aggregate From fada353a068c59b416ce938bf66af2131a2f58f1 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 16 Apr 2019 13:00:39 -0500 Subject: [PATCH 05/39] Checkstyle fix --- dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java b/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java index 9e43d1f9da..feff8fbda7 100644 --- a/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java +++ b/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java @@ -14,13 +14,14 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import net.cnri.util.StreamTable; import net.handle.hdllib.Encoder; import net.handle.hdllib.HandleException; import net.handle.hdllib.HandleStorage; import net.handle.hdllib.HandleValue; import net.handle.hdllib.ScanCallback; import net.handle.hdllib.Util; -import net.cnri.util.StreamTable; + import org.apache.logging.log4j.Logger; import org.dspace.core.Context; import org.dspace.handle.factory.HandleServiceFactory; From 5bfe44f93fdda82c0c85e1bf10c62055ccdeec1e Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Tue, 20 Dec 2016 15:04:31 -0500 Subject: [PATCH 06/39] Begin patching in Velocity --- dspace-api/pom.xml | 6 + .../src/main/java/org/dspace/core/Email.java | 194 ++++++++++++------ 2 files changed, 137 insertions(+), 63 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 4298cfd21e..6fed3c04a6 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -756,6 +756,12 @@ json 20180130 + + org.apache.velocity + velocity + 1.7 + jar + diff --git a/dspace-api/src/main/java/org/dspace/core/Email.java b/dspace-api/src/main/java/org/dspace/core/Email.java index 0fcf911a35..1684d0e48a 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -16,12 +16,15 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.io.StringWriter; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.Iterator; import java.util.List; +import java.util.Properties; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; @@ -39,7 +42,14 @@ import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.internet.ParseException; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.runtime.log.Log4JLogChute; +import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; @@ -120,37 +130,54 @@ public class Email { /** * The arguments to fill out */ - private List arguments; + private final List arguments; /** * The recipients */ - private List recipients; + private final List recipients; /** * Reply to field, if any */ private String replyTo; - private List attachments; - private List moreAttachments; + private final List attachments; + private final List moreAttachments; /** * The character set this message will be sent in */ private String charset; - private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(Email.class); + private static final Logger LOG = LogManager.getLogger(); + + /** Velocity template settings. */ + private static final Properties VELOCITY_PROPERTIES = new Properties(); + static { + VELOCITY_PROPERTIES.put("runtime.log.logsystem.class", + Log4JLogChute.class.getCanonicalName()); + VELOCITY_PROPERTIES.put("resource.loader", "classpath"); + VELOCITY_PROPERTIES.put("classpath.resource.loader.description", + "Velocity Classpath Resource Loader"); + VELOCITY_PROPERTIES.put("classpath.resource.loader.class", + ClasspathResourceLoader.class.getCanonicalName()); + VELOCITY_PROPERTIES.put("classpath.resource.loader.cache", "true"); + } + + /** Velocity template for a message body */ + private Template template; /** * Create a new email message. */ public Email() { - arguments = new ArrayList(50); - recipients = new ArrayList(50); - attachments = new ArrayList(10); - moreAttachments = new ArrayList(10); + arguments = new ArrayList<>(50); + recipients = new ArrayList<>(50); + attachments = new ArrayList<>(10); + moreAttachments = new ArrayList<>(10); subject = ""; + template = null; content = ""; replyTo = null; charset = null; @@ -166,15 +193,15 @@ public class Email { } /** - * Set the content of the message. Setting this "resets" the message - * formatting -addArgument will start. Comments and any + * Set the content of the message. Setting this also "resets" the message + * formatting - addArgument will start over. Comments and any * "Subject:" line must be stripped. * * @param cnt the content of the message */ public void setContent(String cnt) { content = cnt; - arguments = new ArrayList(); + arguments.clear(); } /** @@ -235,14 +262,14 @@ public class Email { } /** - * "Reset" the message. Clears the arguments and recipients, but leaves the - * subject and content intact. + * "Reset" the message. Clears the arguments, attachments and recipients, + * but leaves the subject and content intact. */ public void reset() { - arguments = new ArrayList(50); - recipients = new ArrayList(50); - attachments = new ArrayList(10); - moreAttachments = new ArrayList(10); + arguments.clear(); + recipients.clear(); + attachments.clear(); + moreAttachments.clear(); replyTo = null; charset = null; } @@ -254,7 +281,8 @@ public class Email { * @throws IOException if IO error */ public void send() throws MessagingException, IOException { - ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService(); + ConfigurationService config + = DSpaceServicesFactory.getInstance().getConfigurationService(); // Get the mail configuration properties String from = config.getProperty("mail.from.address"); @@ -280,15 +308,35 @@ public class Email { } // Format the mail message - Object[] args = arguments.toArray(); - String fullMessage = MessageFormat.format(content, args); - Date date = new Date(); + VelocityEngine templateEngine = new VelocityEngine(); + templateEngine.init(VELOCITY_PROPERTIES); + org.apache.velocity.context.Context ctx = new VelocityContext(); + ctx.put("config", new UnmodifiableConfigurationService(config)); + ctx.put("params", Collections.unmodifiableList(arguments)); + + if (null == template) { // No template, so look for a String of content. + if (null == content) { // SNH -- see constructor. + // No template and no content -- PANIC!!! + LOG.error("Email has no body"); + template = new Template(); + template.setData("No content."); + } else { // Turn content into a template. + template = new Template(); + template.setData(content); + } + } + + StringWriter writer = new StringWriter(); + template.merge(ctx, writer); + String fullMessage = writer.toString(); + + Date date = new Date(); message.setSentDate(date); message.setFrom(new InternetAddress(from)); // Set the subject of the email (may contain parameters) - String fullSubject = MessageFormat.format(subject, args); + String fullSubject = MessageFormat.format(subject, arguments.toArray()); if (charset != null) { message.setSubject(fullSubject, charset); } else { @@ -309,35 +357,24 @@ public class Email { BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText(fullMessage); multipart.addBodyPart(messageBodyPart); - if (!attachments.isEmpty()) { - for (Iterator iter = attachments.iterator(); iter.hasNext(); ) { - FileAttachment f = iter.next(); - // add the file - messageBodyPart = new MimeBodyPart(); - messageBodyPart.setDataHandler(new DataHandler( - new FileDataSource(f.file))); - messageBodyPart.setFileName(f.name); - multipart.addBodyPart(messageBodyPart); - } - message.setContent(multipart); + for (FileAttachment attachment : attachments) { + // add the file + messageBodyPart = new MimeBodyPart(); + messageBodyPart.setDataHandler(new DataHandler( + new FileDataSource(attachment.file))); + messageBodyPart.setFileName(attachment.name); + multipart.addBodyPart(messageBodyPart); } - if (!moreAttachments.isEmpty()) { - for (Iterator iter = moreAttachments.iterator(); iter.hasNext(); ) { - InputStreamAttachment isa = iter.next(); - // add the stream - messageBodyPart = new MimeBodyPart(); - messageBodyPart.setDataHandler( - new DataHandler(new InputStreamDataSource( - isa.name, - isa.mimetype, - isa.is) - ) - ); - messageBodyPart.setFileName(isa.name); - multipart.addBodyPart(messageBodyPart); - } - message.setContent(multipart); + message.setContent(multipart); + for (InputStreamAttachment attachment : moreAttachments) { + // add the stream + messageBodyPart = new MimeBodyPart(); + messageBodyPart.setDataHandler(new DataHandler( + new InputStreamDataSource(attachment.name,attachment.mimetype,attachment.is))); + messageBodyPart.setFileName(attachment.name); + multipart.addBodyPart(messageBodyPart); } + message.setContent(multipart); } if (replyTo != null) { @@ -365,15 +402,15 @@ public class Email { text.append('\n').append(fullMessage); - log.info(text); + LOG.info(text); } else { Transport.send(message); } } /** - * Get the template for an email message. The message is suitable for - * inserting values using java.text.MessageFormat. + * Get the plain-text template for an email message. The message is suitable for + * inserting values using {@link java.text.MessageFormat}. * * @param emailFile full name for the email template, for example "/dspace/config/emails/register". * @return the email object, with the content and subject filled out from @@ -449,6 +486,18 @@ public class Email { * throws a MessagingException. */ + /** + * Associate the message with an external Velocity + * {@link org.apache.velocity.Template}. You should also supply a subject + * using {@link #setSubject(java.lang.String)}. + * + * @param templateName simple name to be looked up in the Velocity template + * resources. + */ + public void setTemplate(String templateName) { + template = Velocity.getTemplate(templateName); + } + /** * Test method to send an email to check email server settings * @@ -479,18 +528,12 @@ public class Email { return; } e.send(); - } catch (MessagingException me) { + } catch (MessagingException | IOException me) { System.err.println("\nError sending email:"); System.err.println(" - Error: " + me); System.err.println("\nPlease see the DSpace documentation for assistance.\n"); System.err.println("\n"); System.exit(1); - } catch (IOException e1) { - System.err.println("\nError sending email:"); - System.err.println(" - Error: " + e1); - System.err.println("\nPlease see the DSpace documentation for assistance.\n"); - System.err.println("\n"); - System.exit(1); } System.out.println("\nEmail sent successfully!\n"); } @@ -532,9 +575,9 @@ public class Email { * @author arnaldo */ public class InputStreamDataSource implements DataSource { - private String name; - private String contentType; - private ByteArrayOutputStream baos; + private final String name; + private final String contentType; + private final ByteArrayOutputStream baos; InputStreamDataSource(String name, String contentType, InputStream inputStream) throws IOException { this.name = name; @@ -568,4 +611,29 @@ public class Email { } } + /** + * Wrap ConfigurationService to prevent templates from modifying the configuration. + */ + private class UnmodifiableConfigurationService { + private final ConfigurationService configurationService; + + /** + * Swallow an instance of ConfigurationService. + * + * @param cs the real instance, to be wrapped. + */ + public UnmodifiableConfigurationService(ConfigurationService cs) { + configurationService = cs; + } + + /** + * Look up a key in the actual ConfigurationService. + * + * @param key to be looked up in the DSpace configuration. + * @return whatever value ConfigurationService associates with {@code key}. + */ + public String get(String key) { + return configurationService.getProperty(key); + } + } } From 3bea69ae82bab6ea1b4cb19db04e99aa1f5c7a0e Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Sun, 18 Mar 2018 13:20:23 -0400 Subject: [PATCH 07/39] [DS-3872] Upgrade to Velocity v2. --- dspace-api/pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 6fed3c04a6..5fd64a4750 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -756,10 +756,11 @@ json 20180130 + org.apache.velocity - velocity - 1.7 + velocity-engine-core + 2.0 jar From b75c5e1babe9663439b78d2f1b59c158856e0ff3 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Sun, 18 Mar 2018 13:21:34 -0400 Subject: [PATCH 08/39] [DS-3872] Convert MessageFormat email templates to VTL. --- dspace/config/emails/bte_batch_import_error | 22 +++++----- dspace/config/emails/bte_batch_import_success | 18 ++++----- dspace/config/emails/change_password | 18 ++++----- dspace/config/emails/doi_maintenance_error | 32 +++++++-------- dspace/config/emails/export_error | 22 +++++----- dspace/config/emails/export_success | 20 +++++----- dspace/config/emails/feedback | 40 +++++++++---------- dspace/config/emails/flowtask_notify | 32 +++++++-------- dspace/config/emails/harvesting_error | 32 +++++++-------- dspace/config/emails/healthcheck | 16 ++++---- dspace/config/emails/internal_error | 40 +++++++++---------- dspace/config/emails/register | 18 ++++----- dspace/config/emails/registration_notify | 30 +++++++------- dspace/config/emails/request_item.admin | 12 +++--- dspace/config/emails/request_item.author | 12 +++--- dspace/config/emails/submit_archive | 20 +++++----- dspace/config/emails/submit_reject | 28 ++++++------- dspace/config/emails/submit_task | 28 ++++++------- dspace/config/emails/subscription | 16 ++++---- dspace/config/emails/suggest | 38 +++++++++--------- 20 files changed, 246 insertions(+), 248 deletions(-) diff --git a/dspace/config/emails/bte_batch_import_error b/dspace/config/emails/bte_batch_import_error index 11657f29df..d3754d1363 100644 --- a/dspace/config/emails/bte_batch_import_error +++ b/dspace/config/emails/bte_batch_import_error @@ -1,17 +1,17 @@ -# Email sent to DSpace users when they BTE batch import fails. -# -# Parameters: {0} the export error -# {1} the URL to the feedback page -# -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: DSpace - The batch import was not completed. +## Email sent to DSpace users when they BTE batch import fails. +## +## Parameters: {0} the export error +## {1} the URL to the feedback page +## +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'DSpace - The batch import was not completed.') The batch import you initiated from the DSpace UI was not completed, due to the following reason: - {0} + ${params[0]} For more information you may contact your system administrator: - {1} + ${params[1]} diff --git a/dspace/config/emails/bte_batch_import_success b/dspace/config/emails/bte_batch_import_success index 930ccd82ae..a56a2dbebe 100644 --- a/dspace/config/emails/bte_batch_import_success +++ b/dspace/config/emails/bte_batch_import_success @@ -1,14 +1,14 @@ -# Email sent to DSpace users when they successfully batch import items via BTE. -# -# Parameters: {0} the filepath to the mapfile created by the batch import -# -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: DSpace - Batch import successfully completed +## Email sent to DSpace users when they successfully batch import items via BTE. +## +## Parameters: {0} the filepath to the mapfile created by the batch import +## +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'DSpace - Batch import successfully completed') The batch item import you initiated from the DSpace UI has completed successfully. -You may find the mapfile for the import in the following path: {0} +You may find the mapfile for the import in the following path: ${params[0]} The DSpace Team diff --git a/dspace/config/emails/change_password b/dspace/config/emails/change_password index 9fca59f340..6319d8b736 100644 --- a/dspace/config/emails/change_password +++ b/dspace/config/emails/change_password @@ -1,16 +1,16 @@ -# Email sent to DSpace users when they forget their password. -# -# Parameters: {0} is expanded to a special URL -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: Change Password Request +## Email sent to DSpace users when they forget their password. +## +## Parameters: {0} is expanded to a special URL +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'Change Password Request') To change the password for your DSpace account, please click the link below: - {0} + ${params[0]} If you need assistance with your account, please email -dspace-help@myu.edu or call us at xxx-555-xxxx. +${config.get("mail.admin")} or call us at xxx-555-xxxx. The DSpace Team diff --git a/dspace/config/emails/doi_maintenance_error b/dspace/config/emails/doi_maintenance_error index be60904e7c..5424432f64 100644 --- a/dspace/config/emails/doi_maintenance_error +++ b/dspace/config/emails/doi_maintenance_error @@ -1,18 +1,18 @@ -# E-mail sent to designated address when a metadata update, registration -# or reserveration of a doi fails -# -# Parameters: {0} action (updating metadata of, registering or reserving) -# {1} Date & Time -# {2} resource type text -# {3} resource id -# {4} doi -# {5} reason -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: DSpace: Error {0} DOI {3} +## E-mail sent to designated address when a metadata update, registration +## or reservation of a DOI fails. +## +## Parameters: {0} action (updating metadata of, registering or reserving) +## {1} Date & Time +## {2} resource type text +## {3} resource id +## {4} DOI +## {5} reason +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = "DSpace: Error ${params[0]} DOI ${params[3]}") -Date: {1} +Date: ${params[1]} -{0} DOI {4} for {2} with ID {3} failed: -{5} +${params[0]} DOI ${params[4]} for ${params[2]} with ID ${params[3]} failed: +${params[5]} diff --git a/dspace/config/emails/export_error b/dspace/config/emails/export_error index 571df69553..79468c281e 100644 --- a/dspace/config/emails/export_error +++ b/dspace/config/emails/export_error @@ -1,17 +1,17 @@ -# Email sent to DSpace users when they successfully export an item or collection. -# -# Parameters: {0} the export error -# {1} the URL to the feedback page -# -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: DSpace - The item export you requested was not completed. +## Email sent to DSpace users when they successfully export an item or collection. +## +## Parameters: {0} the export error +## {1} the URL to the feedback page +## +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'DSpace - The item export you requested was not completed.') The item export you requested was not completed, due to the following reason: - {0} + ${params[0]} For more information you may contact your system administrator: - {1} + ${params[1]} diff --git a/dspace/config/emails/export_success b/dspace/config/emails/export_success index 2396e5ce5e..b97a379873 100644 --- a/dspace/config/emails/export_success +++ b/dspace/config/emails/export_success @@ -1,17 +1,17 @@ -# Email sent to DSpace users when they successfully export an item or collection. -# -# Parameters: {0} is expanded to a special URL -# {1} configurable time (hours) an export file will be kept -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: DSpace - Item export requested is ready for download +## Email sent to DSpace users when they successfully export an item or collection. +## +## Parameters: {0} is expanded to a special URL +## {1} configurable time (hours) an export file will be kept +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'DSpace - Item export requested is ready for download') The item export you requested from the repository is now ready for download. You may download the compressed file using the following link: -{0} +${params[0]} -This file will remain available for at least {1} hours. +This file will remain available for at least ${params[1]} hours. The DSpace Team diff --git a/dspace/config/emails/feedback b/dspace/config/emails/feedback index e7f972e4b5..7998367c26 100644 --- a/dspace/config/emails/feedback +++ b/dspace/config/emails/feedback @@ -1,26 +1,26 @@ -# E-mail sent with the information filled out in a feedback form. -# -# Parameters: {0} current date -# {1} email address that the user provided -# {2} logged in as -# {3} page that the user was on when they selected feedback -# {4} User-Agent HTTP Header -# {5} Session Id -# {6} The user's comments -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: Feedback Form Information +## E-mail sent with the information filled out in a feedback form. +## +## Parameters: {0} current date +## {1} email address that the user provided +## {2} logged in as +## {3} page that the user was on when they selected feedback +## {4} User-Agent HTTP Header +## {5} Session Id +## {6} The user's comments +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'Feedback Form Information') Comments: -{6} +${params[6]} -Date: {0} -Email: {1} -Logged In As: {2} -Referring Page: {3} -User Agent: {4} -Session: {5} +Date: ${params[0]} +Email: ${params[1]} +Logged In As: ${params[2]} +Referring Page: ${params[3]} +User Agent: ${params[4]} +Session: ${params[5]} diff --git a/dspace/config/emails/flowtask_notify b/dspace/config/emails/flowtask_notify index 4b494180e7..7e5286e307 100644 --- a/dspace/config/emails/flowtask_notify +++ b/dspace/config/emails/flowtask_notify @@ -1,23 +1,23 @@ -# Workflow curation task notification email message -# -# {0} Title of submission -# {1} Name of collection -# {2} Submitter's name -# {3} Name of task operating -# {4} Task result -# {5} Workflow action taken -# -Subject: DSpace: Curation Task Report +## Workflow curation task notification email message +## +## {0} Title of submission +## {1} Name of collection +## {2} Submitter's name +## {3} Name of task operating +## {4} Task result +## {5} Workflow action taken +## +#set($subject = 'DSpace: Curation Task Report') -Title: {0} -Collection: {1} -Submitted by: {2} +Title: ${params[0]} +Collection: ${params[1]} +Submitted by: ${params[2]} -Curation task {3} has been performed +Curation task ${params[3]} has been performed with the following result: -{4} +${params[4]} -Action taken on the submission: {5} +Action taken on the submission: ${params[5]} DSpace diff --git a/dspace/config/emails/harvesting_error b/dspace/config/emails/harvesting_error index e863be8424..d14b51fe82 100644 --- a/dspace/config/emails/harvesting_error +++ b/dspace/config/emails/harvesting_error @@ -1,20 +1,20 @@ -# E-mail sent to designated address when a harvest process fails -# -# Parameters: {0} Collection id -# {1} Date & time -# {2} Status flag -# {3} Exception message -# {4} Exception stack trace -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: DSpace: Harvesting Error -Collection {0} failed on harvest: +## E-mail sent to designated address when a harvest process fails +## +## Parameters: {0} Collection id +## {1} Date & time +## {2} Status flag +## {3} Exception message +## {4} Exception stack trace +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'DSpace: Harvesting Error') +Collection ${params[0]} failed on harvest: -Date: {1} -Status Flag: {2} +Date: ${params[1]} +Status Flag: ${params[2]} -{3} +${params[3]} Exception: -{4} +${params[4]} diff --git a/dspace/config/emails/healthcheck b/dspace/config/emails/healthcheck index de73373946..bee4d4dec2 100644 --- a/dspace/config/emails/healthcheck +++ b/dspace/config/emails/healthcheck @@ -1,11 +1,9 @@ -# E-mail sent by the healthcheck command to whomever is mentioned as -e parameter -# -# Parameters: {0} is the output of healthcheck command -# See org.dspace.core.Email for information on the format of this file. -# -Subject: Repository healthcheck +## E-mail sent by the healthcheck command to whomever is mentioned as -e parameter. +## +## Parameters: {0} is the output of healthcheck command +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'Repository healthcheck') The healthcheck finished with the following output: -{0} - - +${params[0]} diff --git a/dspace/config/emails/internal_error b/dspace/config/emails/internal_error index 9f1c8db7a4..ee622f4b38 100644 --- a/dspace/config/emails/internal_error +++ b/dspace/config/emails/internal_error @@ -1,24 +1,24 @@ -# E-mail sent to designated address when an internal server error occurs -# -# Parameters: {0} DSpace server URL -# {1} Date & time -# {2} Session ID -# {3} URL + HTTP parameters, if any -# {4} Exception stack trace -# {5} User details -# {6} IP address -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: DSpace: Internal Server Error -An internal server error occurred on {0}: +## E-mail sent to designated address when an internal server error occurs +## +## Parameters: {0} DSpace server URL +## {1} Date & time +## {2} Session ID +## {3} URL + HTTP parameters, if any +## {4} Exception stack trace +## {5} User details +## {6} IP address +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'DSpace: Internal Server Error') +An internal server error occurred on ${params[0]}: -Date: {1} -Session ID: {2} -User: {5} -IP address: {6} +Date: ${params[1]} +Session ID: ${params[2]} +User: ${params[5]} +IP address: ${params[6]} -{3} +${params[3]} Exception: -{4} +${params[4]} diff --git a/dspace/config/emails/register b/dspace/config/emails/register index 7439da86dd..15917195f2 100644 --- a/dspace/config/emails/register +++ b/dspace/config/emails/register @@ -1,16 +1,16 @@ -# E-mail sent to DSpace users when they register for an account -# -# Parameters: {0} is expanded to a special registration URL -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: DSpace Account Registration +## E-mail sent to DSpace users when they register for an account +## +## Parameters: {0} is expanded to a special registration URL +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = "${config.get("dspace.name")} Account Registration") To complete registration for a DSpace account, please click the link below: - {0} + ${params[0]} If you need assistance with your account, please email -dspace-help@myu.edu or call us at xxx-555-xxxx. +${config.get("mail.admin")} or call us at xxx-555-xxxx. The DSpace Team diff --git a/dspace/config/emails/registration_notify b/dspace/config/emails/registration_notify index 9802ae887d..96c87fa63d 100644 --- a/dspace/config/emails/registration_notify +++ b/dspace/config/emails/registration_notify @@ -1,17 +1,17 @@ -# Registration notification email -# -# Parameters: {0} The name of the DSpace instance -# {1} The URL of the DSpace instance -# {2} Name: -# {3} Email: -# {4} Registration Date: -# -# See org.dspace.core.Email for information on the format of this file. -# -Subject: DSpace: Registration Notification +## Registration notification email +## +## Parameters: {0} The name of the DSpace instance +## {1} The URL of the DSpace instance +## {2} Name: +## {3} Email: +## {4} Registration Date: +## +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'DSpace: Registration Notification') -A new user has registered on {0} at {1}: +A new user has registered on ${params[0]} at ${params[1]}: -Name: {2} -Email: {3} -Date: {4} +Name: ${params[2]} +Email: ${params[3]} +Date: ${params[4]} diff --git a/dspace/config/emails/request_item.admin b/dspace/config/emails/request_item.admin index 7611efb204..849079574b 100644 --- a/dspace/config/emails/request_item.admin +++ b/dspace/config/emails/request_item.admin @@ -1,8 +1,8 @@ -Subject: Request for Open Access +#set($subject = 'Request for Open Access') -{3}, with address {4}, -requested the following document/file to be in Open Access: +${params[3]}, with address ${params[4]}, +requested the following document/file to be in Open Access: -Document Handle:{1} -File ID: {0} -Token:{2} \ No newline at end of file +Document Handle:${params[1]} +File ID: ${params[0]} +Token:${params[2]} diff --git a/dspace/config/emails/request_item.author b/dspace/config/emails/request_item.author index 3ea529f46d..9166d31d78 100644 --- a/dspace/config/emails/request_item.author +++ b/dspace/config/emails/request_item.author @@ -1,17 +1,17 @@ -Subject: Request copy of document +#set($subject = 'Request copy of document') -Dear {7}, +Dear ${params[7]}, -A user of {9}, named {0} and using the email {1}, requested a copy of the file(s) associated with the document: "{4}" ({3}) submitted by you. +A user of ${params[9]}, named ${params[0]} and using the email ${params[1]}, requested a copy of the file(s) associated with the document: "${params[4]}" (${params[3]}) submitted by you. This request came along with the following message: -"{5}" +"${params[5]}" -To answer, click {6}. Whether you choose to grant or deny the request, we think that it''s in your best interest to respond. +To answer, click ${params[6]}. Whether you choose to grant or deny the request, we think that it''s in your best interest to respond. IF YOU ARE NOT AN AUTHOR OF THIS DOCUMENT, and only submitted the document on the author''s behalf, PLEASE REDIRECT THIS MESSAGE TO THE AUTHOR(S). Only the author(s) should answer the request to send a copy. IF YOU ARE AN AUTHOR OF THE REQUESTED DOCUMENT, thank you for your cooperation! -If you have any questions concerning this request, please contact {10}. \ No newline at end of file +If you have any questions concerning this request, please contact ${params[10]}. diff --git a/dspace/config/emails/submit_archive b/dspace/config/emails/submit_archive index 39e3c105a2..d3d62f7f4d 100644 --- a/dspace/config/emails/submit_archive +++ b/dspace/config/emails/submit_archive @@ -1,18 +1,18 @@ -# Item Archived email message -# -# {0} Title of submission -# {1} Name of collection -# {2} handle -# -Subject: DSpace: Submission Approved and Archived +## Item Archived email message +## +## {0} Title of submission +## {1} Name of collection +## {2} handle +## +#set($subject = 'DSpace: Submission Approved and Archived') -You submitted: {0} +You submitted: ${params[0]} -To collection: {1} +To collection: ${params[1]} Your submission has been accepted and archived in DSpace, and it has been assigned the following identifier: -{2} +${params[2]} Please use this identifier when citing your submission. diff --git a/dspace/config/emails/submit_reject b/dspace/config/emails/submit_reject index 7408546462..44e6cf2cd9 100644 --- a/dspace/config/emails/submit_reject +++ b/dspace/config/emails/submit_reject @@ -1,23 +1,23 @@ -# Rejection email message -# -# {0} Title of submission -# {1} Name of collection -# {2} Name of the rejector -# {3} Reason for the rejection -# {4} Link to 'My DSpace' page -# -Subject: DSpace: Submission Rejected +## Rejection email message +## +## {0} Title of submission +## {1} Name of collection +## {2} Name of the rejector +## {3} Reason for the rejection +## {4} Link to 'My DSpace' page +## +#set($subject = 'DSpace: Submission Rejected') -You submitted: {0} +You submitted: ${params[0]} -To collection: {1} +To collection: ${params[1]} -Your submission has been rejected by {2} +Your submission has been rejected by ${params[2]} with the following explanation: -{3} +${params[3]} Your submission has not been deleted. You can access it from your -"My DSpace" page: {4} +"My DSpace" page: ${params[4]} DSpace diff --git a/dspace/config/emails/submit_task b/dspace/config/emails/submit_task index b2354c8252..8c8b4a7e72 100644 --- a/dspace/config/emails/submit_task +++ b/dspace/config/emails/submit_task @@ -1,23 +1,23 @@ -# Workflow task email message -# -# {0} Title of submission -# {1} Name of collection -# {2} submitter's name -# {3} Description of task -# {4} link to 'my DSpace' page -# -Subject: DSpace: You have a new task +## Workflow task email message +## +## {0} Title of submission +## {1} Name of collection +## {2} submitter's name +## {3} Description of task +## {4} link to 'my DSpace' page +## +#set($subject = 'DSpace: You have a new task') A new item has been submitted: -Title: {0} -Collection: {1} -Submitted by: {2} +Title: ${params[0]} +Collection: ${params[1]} +Submitted by: ${params[2]} -{3} +${params[3]} To claim this task, please visit your "My DSpace" -page: {4} +page: ${params[4]} Many thanks! diff --git a/dspace/config/emails/subscription b/dspace/config/emails/subscription index 6310a36c36..58a29c25ab 100644 --- a/dspace/config/emails/subscription +++ b/dspace/config/emails/subscription @@ -1,12 +1,12 @@ -# E-mail sent to DSpace users when new items appear in collections they are -# subscribed to -# -# Parameters: {0} is the details of the new collections and items -# See org.dspace.core.Email for information on the format of this file. -# -Subject: DSpace Subscription +## E-mail sent to DSpace users when new items appear in collections they are +## subscribed to +## +## Parameters: {0} is the details of the new collections and items +## See org.dspace.core.Email for information on the format of this file. +## +$set($subject = 'DSpace Subscription') New items are available in the collections you have subscribed to: -{0} +${params[0]} DSpace diff --git a/dspace/config/emails/suggest b/dspace/config/emails/suggest index 4c4db3efac..2f90b69ce1 100644 --- a/dspace/config/emails/suggest +++ b/dspace/config/emails/suggest @@ -1,25 +1,25 @@ -# E-mail sent with the information filled out in a suggest form. -# -# Parameters: {0} recipient name -# {1} sender name -# {2} repository name -# {3} item title -# {4} item handle URI -# {5} item local URL - may be used in lieu of {4} if not using handle server -# {6} collection name -# {7} sender message -# See org.dspace.core.Email for information on the format of this file. -# -Subject: An item of interest from DSpace +## E-mail sent with the information filled out in a suggest form. +## +## Parameters: {0} recipient name +## {1} sender name +## {2} repository name +## {3} item title +## {4} item handle URI +## {5} item local URL - may be used in lieu of {4} if not using handle server +## {6} collection name +## {7} sender message +## See org.dspace.core.Email for information on the format of this file. +## +#set($subject = 'An item of interest from DSpace') -Hello {0}: +Hello ${params[0]}: -{1} requested we send you this email regarding an item available in {2}. +${params[1]} requested we send you this email regarding an item available in ${params[2]}. -Title: {3} -Location: {5} -In Collection: {6} -Personal Message: {7} +Title: ${params[3]} +Location: ${params[5]} +In Collection: ${params[6]} +Personal Message: ${params[7]} The DSpace digital repository system captures, stores, indexes, preserves, and distributes digital material. For more information, visit www.dspace.org From 66191be2aa6da9ab4b317c9c14670ba86f9d789c Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Sun, 18 Mar 2018 13:23:21 -0400 Subject: [PATCH 09/39] [DS-3872] Restore ability to set Subject: from template text. --- .../src/main/java/org/dspace/core/Email.java | 58 +++++++++++-------- dspace/config/dspace.cfg | 3 + 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/core/Email.java b/dspace-api/src/main/java/org/dspace/core/Email.java index 1684d0e48a..325dfdb830 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -48,7 +48,6 @@ import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; -import org.apache.velocity.runtime.log.Log4JLogChute; import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; @@ -70,26 +69,23 @@ import org.dspace.services.factory.DSpaceServicesFactory; * dspace-dir/config/emails/ (which also includes the subject.) * arg0 and arg1 are arguments to fill out the * message with. - *

- *

- * Emails are formatted using java.text.MessageFormat. - * Additionally, comment lines (starting with '#') are stripped, and if a line - * starts with "Subject:" the text on the right of the colon is used for the - * subject line. For example: + *

+ * Emails are formatted using Apache Velocity. Headers such as Subject may be + * supplied by the template, by defining them using #set(). Example: *

* *
  *
- *     # This is a comment line which is stripped
- *     #
- *     # Parameters:   {0}  is a person's name
- *     #               {1}  is the name of a submission
- *     #
- *     Subject: Example e-mail
+ *     ## This is a comment line which is stripped
+ *     ##
+ *     ## Parameters:   {0}  is a person's name
+ *     ##               {1}  is the name of a submission
+ *     ##
+ *     #set($subject = 'Example e-mail')
  *
- *     Dear {0},
+ *     Dear ${params[0]},
  *
- *     Thank you for sending us your submission "{1}".
+ *     Thank you for sending us your submission "${params[1]}".
  *
  * 
* @@ -107,11 +103,6 @@ import org.dspace.services.factory.DSpaceServicesFactory; * * * - *

- * Note that parameters like {0} cannot be placed in the subject - * of the e-mail; they won't get filled out. - *

- * * @author Robert Tansley * @author Jim Downing - added attachment handling code * @author Adan Roman Ruiz at arvo.es - added inputstream attachment handling code @@ -155,8 +146,6 @@ public class Email { /** Velocity template settings. */ private static final Properties VELOCITY_PROPERTIES = new Properties(); static { - VELOCITY_PROPERTIES.put("runtime.log.logsystem.class", - Log4JLogChute.class.getCanonicalName()); VELOCITY_PROPERTIES.put("resource.loader", "classpath"); VELOCITY_PROPERTIES.put("classpath.resource.loader.description", "Velocity Classpath Resource Loader"); @@ -275,7 +264,15 @@ public class Email { } /** - * Sends the email. + * Sends the email. If the template defines a Velocity context property + * named among the values of DSpace configuration property + * {@code mail.message.headers} then that name and its value will be added + * to the message's headers. + * + *

"subject" is treated specially: if {@link setSubject()} has not been called, + * the value of any "subject" property will be used as if setSubject had + * been called with that value. Thus a template may define its subject, but + * the caller may override it. * * @throws MessagingException if there was a problem sending the mail. * @throws IOException if IO error @@ -307,7 +304,7 @@ public class Email { i.next())); } - // Format the mail message + // Format the mail message body VelocityEngine templateEngine = new VelocityEngine(); templateEngine.init(VELOCITY_PROPERTIES); @@ -331,10 +328,23 @@ public class Email { template.merge(ctx, writer); String fullMessage = writer.toString(); + // Set some message header fields Date date = new Date(); message.setSentDate(date); message.setFrom(new InternetAddress(from)); + // Get headers defined by the template. + for (String headerName : config.getArrayProperty("mail.message.headers")) { + String headerValue = (String) ctx.get(headerName); + if ("subject".equalsIgnoreCase(headerName)) { + if (null != subject) { + subject = headerValue; + } + } else { + message.setHeader(headerName, headerValue); + } + } + // Set the subject of the email (may contain parameters) String fullSubject = MessageFormat.format(subject, arguments.toArray()); if (charset != null) { diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 6b2581a497..04f2e41a9b 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -163,6 +163,9 @@ mail.allowed.referrers = ${dspace.hostname} # This is especially useful for development and test environments where production data is used when testing functionality. #mail.server.disabled = false +# Message headers which may be set by a message template. +mail.message.headers = subject + ##### Asset Storage (bitstreams / files) ###### # Moved to config/spring/api/bitstore.xml From d94264bc79568e00ec16308b09906760b1c568c6 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Sun, 18 Mar 2018 13:52:15 -0400 Subject: [PATCH 10/39] [DS-3872] Support 'charset' header; remove old code I had missed. --- .../src/main/java/org/dspace/core/Email.java | 65 ++++++------------- dspace/config/dspace.cfg | 1 + 2 files changed, 22 insertions(+), 44 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/core/Email.java b/dspace-api/src/main/java/org/dspace/core/Email.java index 325dfdb830..ef56708ff1 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -312,8 +312,9 @@ public class Email { ctx.put("config", new UnmodifiableConfigurationService(config)); ctx.put("params", Collections.unmodifiableList(arguments)); - if (null == template) { // No template, so look for a String of content. - if (null == content) { // SNH -- see constructor. + if (null == template) { + // No template, so look for a String of content. + if (null == content) { // SNH -- see constructor // No template and no content -- PANIC!!! LOG.error("Email has no body"); template = new Template(); @@ -340,6 +341,8 @@ public class Email { if (null != subject) { subject = headerValue; } + } else if ("charset".equalsIgnoreCase(headerName)) { + charset = headerValue; } else { message.setHeader(headerName, headerValue); } @@ -419,12 +422,14 @@ public class Email { } /** - * Get the plain-text template for an email message. The message is suitable for - * inserting values using {@link java.text.MessageFormat}. + * Get the plain-text template for an email message. The message is suitable + * for inserting values using Apache Velocity. + * + * @param emailFile + * full name for the email template, for example "/dspace/config/emails/register". + * + * @return the email object, configured with subject and body. * - * @param emailFile full name for the email template, for example "/dspace/config/emails/register". - * @return the email object, with the content and subject filled out from - * the template * @throws IOException if IO error * if the template couldn't be found, or there was some other * error reading the template @@ -432,54 +437,26 @@ public class Email { public static Email getEmail(String emailFile) throws IOException { String charset = null; - String subject = ""; StringBuilder contentBuffer = new StringBuilder(); - InputStream is = null; - InputStreamReader ir = null; - BufferedReader reader = null; - try { - is = new FileInputStream(emailFile); - ir = new InputStreamReader(is, "UTF-8"); - reader = new BufferedReader(ir); + try ( + InputStream is = new FileInputStream(emailFile); + InputStreamReader ir = new InputStreamReader(is, "UTF-8"); + BufferedReader reader = new BufferedReader(ir); + ) { boolean more = true; while (more) { String line = reader.readLine(); if (line == null) { more = false; - } else if (line.toLowerCase().startsWith("subject:")) { - subject = line.substring(8).trim(); - } else if (line.toLowerCase().startsWith("charset:")) { - charset = line.substring(8).trim(); - } else if (!line.startsWith("#")) { + } + else + { contentBuffer.append(line); contentBuffer.append("\n"); } } - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException ioe) { - // ignore - } - } - if (ir != null) { - try { - ir.close(); - } catch (IOException ioe) { - // ignore - } - } - if (is != null) { - try { - is.close(); - } catch (IOException ioe) { - // ignore - } - } } Email email = new Email(); - email.setSubject(subject); email.setContent(contentBuffer.toString()); if (charset != null) { email.setCharset(charset); @@ -498,7 +475,7 @@ public class Email { /** * Associate the message with an external Velocity - * {@link org.apache.velocity.Template}. You should also supply a subject + * {@link org.apache.velocity.Template}. You may also supply a subject * using {@link #setSubject(java.lang.String)}. * * @param templateName simple name to be looked up in the Velocity template diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 04f2e41a9b..af11af6ba5 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -165,6 +165,7 @@ mail.allowed.referrers = ${dspace.hostname} # Message headers which may be set by a message template. mail.message.headers = subject +mail.message.headers = charset ##### Asset Storage (bitstreams / files) ###### # Moved to config/spring/api/bitstore.xml From 60f72fb90ae03b62aff1e9ecd028d97397308286 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Sun, 18 Mar 2018 15:09:39 -0400 Subject: [PATCH 11/39] [DS-3872] Checkstyle fixes lost in rebasing. --- dspace-api/src/main/java/org/dspace/core/Email.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/core/Email.java b/dspace-api/src/main/java/org/dspace/core/Email.java index ef56708ff1..fb5a9f13a7 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -448,9 +448,7 @@ public class Email { String line = reader.readLine(); if (line == null) { more = false; - } - else - { + } else { contentBuffer.append(line); contentBuffer.append("\n"); } From 9f7b3e53dff0a08829aa68ad68c841051e9314d4 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Sun, 18 Mar 2018 22:17:33 -0400 Subject: [PATCH 12/39] [DS-3872] Align commons-lang3 transitive dependencies. --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index fe79dd3ccc..e8dcc4bb68 100644 --- a/pom.xml +++ b/pom.xml @@ -1176,6 +1176,11 @@ commons-lang3 3.7 + + org.apache.commons + commons-lang3 + 3.5 + commons-logging commons-logging From cb3edadf1f721774194644c4ddaca59b87489c0b Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Sun, 18 Mar 2018 22:18:48 -0400 Subject: [PATCH 13/39] [DS-3872] Load template file into string resource repository, let Velocity figure out how to parse it. --- .../dspace/checker/DailyReportEmailer.java | 2 +- .../src/main/java/org/dspace/core/Email.java | 36 ++++++++++--------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/checker/DailyReportEmailer.java b/dspace-api/src/main/java/org/dspace/checker/DailyReportEmailer.java index 56dabb0460..350facaad5 100644 --- a/dspace-api/src/main/java/org/dspace/checker/DailyReportEmailer.java +++ b/dspace-api/src/main/java/org/dspace/checker/DailyReportEmailer.java @@ -67,7 +67,7 @@ public class DailyReportEmailer { email.setSubject( "Checksum checker Report - " + numberOfBitstreams + " Bitstreams found with POSSIBLE issues on " + hostname); - email.setContent("report is attached ..."); + email.setContent("Checker Report", "report is attached ..."); email.addAttachment(attachment, "checksum_checker_report.txt"); email.addRecipient(ConfigurationManager.getProperty("mail.admin")); email.send(); diff --git a/dspace-api/src/main/java/org/dspace/core/Email.java b/dspace-api/src/main/java/org/dspace/core/Email.java index fb5a9f13a7..fa3796940b 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -48,7 +48,8 @@ import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; -import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; +import org.apache.velocity.runtime.resource.loader.StringResourceLoader; +import org.apache.velocity.runtime.resource.util.StringResourceRepository; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; @@ -112,6 +113,7 @@ public class Email { * The content of the message */ private String content; + private String contentName; /** * The subject of the message @@ -146,12 +148,11 @@ public class Email { /** Velocity template settings. */ private static final Properties VELOCITY_PROPERTIES = new Properties(); static { - VELOCITY_PROPERTIES.put("resource.loader", "classpath"); - VELOCITY_PROPERTIES.put("classpath.resource.loader.description", - "Velocity Classpath Resource Loader"); - VELOCITY_PROPERTIES.put("classpath.resource.loader.class", - ClasspathResourceLoader.class.getCanonicalName()); - VELOCITY_PROPERTIES.put("classpath.resource.loader.cache", "true"); + VELOCITY_PROPERTIES.put(Velocity.RESOURCE_LOADER, "string"); + VELOCITY_PROPERTIES.put("string.resource.loader.description", + "Velocity StringResource loader"); + VELOCITY_PROPERTIES.put("string.resource.loader.class", + StringResourceLoader.class.getName()); } /** Velocity template for a message body */ @@ -170,6 +171,8 @@ public class Email { content = ""; replyTo = null; charset = null; + + Velocity.init(VELOCITY_PROPERTIES); } /** @@ -186,10 +189,12 @@ public class Email { * formatting - addArgument will start over. Comments and any * "Subject:" line must be stripped. * + * @param name a name for this message body * @param cnt the content of the message */ - public void setContent(String cnt) { + public void setContent(String name, String cnt) { content = cnt; + contentName = name; arguments.clear(); } @@ -314,14 +319,13 @@ public class Email { if (null == template) { // No template, so look for a String of content. + StringResourceRepository repo = StringResourceLoader.getRepository(); + repo.putStringResource(contentName, content); if (null == content) { // SNH -- see constructor // No template and no content -- PANIC!!! - LOG.error("Email has no body"); - template = new Template(); - template.setData("No content."); + throw new MessagingException("Email has no body"); } else { // Turn content into a template. - template = new Template(); - template.setData(content); + template = Velocity.getTemplate(contentName); } } @@ -397,7 +401,7 @@ public class Email { } if (disabled) { - StringBuffer text = new StringBuffer( + StringBuilder text = new StringBuilder( "Message not sent due to mail.server.disabled:\n"); Enumeration headers = message.getAllHeaderLines(); @@ -415,7 +419,7 @@ public class Email { text.append('\n').append(fullMessage); - LOG.info(text); + LOG.info(text.toString()); } else { Transport.send(message); } @@ -455,7 +459,7 @@ public class Email { } } Email email = new Email(); - email.setContent(contentBuffer.toString()); + email.setContent(emailFile, contentBuffer.toString()); if (charset != null) { email.setCharset(charset); } From a579f8fe925d6d3fb4d714cb1eae49f9203c4c1f Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Mon, 19 Mar 2018 10:37:32 -0400 Subject: [PATCH 14/39] [DS-3872] Spring Boot looks for Velocity and tries to initialize it as v1. Suppress this. --- .../src/main/java/org/dspace/core/Email.java | 4 +- .../java/org/dspace/app/rest/Application.java | 95 ++++++++++++++++++- 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/core/Email.java b/dspace-api/src/main/java/org/dspace/core/Email.java index fa3796940b..1d19f11e1a 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -234,14 +234,14 @@ public class Email { public void addAttachment(InputStream is, String name, String mimetype) { if (null == mimetype) { - log.error("Null MIME type replaced with '" + DEFAULT_ATTACHMENT_TYPE + LOG.error("Null MIME type replaced with '" + DEFAULT_ATTACHMENT_TYPE + "' for attachment '" + name + "'"); mimetype = DEFAULT_ATTACHMENT_TYPE; } else { try { new ContentType(mimetype); // Just try to parse it. } catch (ParseException ex) { - log.error("Bad MIME type '" + mimetype + LOG.error("Bad MIME type '" + mimetype + "' replaced with '" + DEFAULT_ATTACHMENT_TYPE + "' for attachment '" + name + "'", ex); mimetype = DEFAULT_ATTACHMENT_TYPE; diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java index 0315860178..b1a1a8bd7c 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.velocity.VelocityAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; @@ -47,7 +48,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter * @author Andrea Bollini (andrea.bollini at 4science.it) * @author Tim Donohue */ -@SpringBootApplication +@SpringBootApplication(exclude = VelocityAutoConfiguration.class) public class Application extends SpringBootServletInitializer { private static final Logger log = LoggerFactory.getLogger(Application.class); @@ -143,4 +144,96 @@ public class Application extends SpringBootServletInitializer { } }; } + + /** + * Utility class that will destroy the DSpace Kernel on Spring Boot shutdown + */ + private class DSpaceKernelDestroyer implements ApplicationListener { + private DSpaceKernel kernel; + + public DSpaceKernelDestroyer(DSpaceKernel kernel) { + this.kernel = kernel; + } + + public void onApplicationEvent(final ContextClosedEvent event) { + if (this.kernel != null) { + this.kernel.destroy(); + this.kernel = null; + } + } + } + + /** + * Utility class that will initialize the DSpace Kernel on Spring Boot startup + */ + private class DSpaceKernelInitializer implements ApplicationContextInitializer { + + private transient DSpaceKernel dspaceKernel; + + public void initialize(final ConfigurableApplicationContext applicationContext) { + + String dspaceHome = applicationContext.getEnvironment().getProperty("dspace.dir"); + + this.dspaceKernel = DSpaceKernelManager.getDefaultKernel(); + if (this.dspaceKernel == null) { + DSpaceKernelImpl kernelImpl = null; + try { + kernelImpl = DSpaceKernelInit.getKernel(null); + if (!kernelImpl.isRunning()) { + kernelImpl.start(getProvidedHome(dspaceHome)); // init the kernel + } + this.dspaceKernel = kernelImpl; + + } catch (Exception e) { + // failed to start so destroy it and log and throw an exception + try { + if (kernelImpl != null) { + kernelImpl.destroy(); + } + this.dspaceKernel = null; + } catch (Exception e1) { + // nothing + } + String message = "Failure during ServletContext initialisation: " + e.getMessage(); + log.error(message, e); + throw new RuntimeException(message, e); + } + } + + if (applicationContext.getParent() == null) { + //Set the DSpace Kernel Application context as a parent of the Spring Boot context so that + //we can auto-wire all DSpace Kernel services + applicationContext.setParent(dspaceKernel.getServiceManager().getApplicationContext()); + + //Add a listener for Spring Boot application shutdown so that we can nicely cleanup the DSpace kernel. + applicationContext.addApplicationListener(new DSpaceKernelDestroyer(dspaceKernel)); + } + } + + /** + * Find DSpace's "home" directory. + * Initially look for JNDI Resource called "java:/comp/env/dspace.dir". + * If not found, look for "dspace.dir" initial context parameter. + */ + private String getProvidedHome(String dspaceHome) { + String providedHome = null; + try { + Context ctx = new InitialContext(); + providedHome = (String) ctx.lookup("java:/comp/env/" + DSpaceConfigurationService.DSPACE_HOME); + } catch (Exception e) { + // do nothing + } + + if (providedHome == null) { + if (dspaceHome != null && !dspaceHome.equals("") && + !dspaceHome.equals("${" + DSpaceConfigurationService.DSPACE_HOME + "}")) { + File test = new File(dspaceHome); + if (test.exists() && new File(test, DSpaceConfigurationService.DSPACE_CONFIG_PATH).exists()) { + providedHome = dspaceHome; + } + } + } + return providedHome; + } + } } From db8a5effb39c20113cb5b4470776820a234815d4 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Mon, 19 Mar 2018 12:52:55 -0400 Subject: [PATCH 15/39] [DS-3872] Avoid collision with other Velocity users by making resources local to the engine instance. Also misc. clarifications and cleanups, drop unused new method. --- .../src/main/java/org/dspace/core/Email.java | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/core/Email.java b/dspace-api/src/main/java/org/dspace/core/Email.java index 1d19f11e1a..505501140f 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -146,6 +146,7 @@ public class Email { private static final Logger LOG = LogManager.getLogger(); /** Velocity template settings. */ + private static final String RESOURCE_REPOSITORY_NAME = "Email"; private static final Properties VELOCITY_PROPERTIES = new Properties(); static { VELOCITY_PROPERTIES.put(Velocity.RESOURCE_LOADER, "string"); @@ -153,6 +154,10 @@ public class Email { "Velocity StringResource loader"); VELOCITY_PROPERTIES.put("string.resource.loader.class", StringResourceLoader.class.getName()); + VELOCITY_PROPERTIES.put("string.resource.loader.repository.name", + RESOURCE_REPOSITORY_NAME); + VELOCITY_PROPERTIES.put("string.resource.loader.repository.static", + "false"); } /** Velocity template for a message body */ @@ -171,8 +176,6 @@ public class Email { content = ""; replyTo = null; charset = null; - - Velocity.init(VELOCITY_PROPERTIES); } /** @@ -313,24 +316,25 @@ public class Email { VelocityEngine templateEngine = new VelocityEngine(); templateEngine.init(VELOCITY_PROPERTIES); - org.apache.velocity.context.Context ctx = new VelocityContext(); - ctx.put("config", new UnmodifiableConfigurationService(config)); - ctx.put("params", Collections.unmodifiableList(arguments)); + VelocityContext vctx = new VelocityContext(); + vctx.put("config", new UnmodifiableConfigurationService(config)); + vctx.put("params", Collections.unmodifiableList(arguments)); if (null == template) { // No template, so look for a String of content. - StringResourceRepository repo = StringResourceLoader.getRepository(); + StringResourceRepository repo = (StringResourceRepository) + templateEngine.getApplicationAttribute(RESOURCE_REPOSITORY_NAME); repo.putStringResource(contentName, content); if (null == content) { // SNH -- see constructor // No template and no content -- PANIC!!! throw new MessagingException("Email has no body"); } else { // Turn content into a template. - template = Velocity.getTemplate(contentName); + template = templateEngine.getTemplate(contentName); } } StringWriter writer = new StringWriter(); - template.merge(ctx, writer); + template.merge(vctx, writer); String fullMessage = writer.toString(); // Set some message header fields @@ -340,7 +344,7 @@ public class Email { // Get headers defined by the template. for (String headerName : config.getArrayProperty("mail.message.headers")) { - String headerValue = (String) ctx.get(headerName); + String headerValue = (String) vctx.get(headerName); if ("subject".equalsIgnoreCase(headerName)) { if (null != subject) { subject = headerValue; @@ -370,10 +374,13 @@ public class Email { } } else { Multipart multipart = new MimeMultipart(); + // create the first part of the email BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText(fullMessage); multipart.addBodyPart(messageBodyPart); + + // Add file attachments for (FileAttachment attachment : attachments) { // add the file messageBodyPart = new MimeBodyPart(); @@ -382,7 +389,8 @@ public class Email { messageBodyPart.setFileName(attachment.name); multipart.addBodyPart(messageBodyPart); } - message.setContent(multipart); + + // Add stream attachments for (InputStreamAttachment attachment : moreAttachments) { // add the stream messageBodyPart = new MimeBodyPart(); @@ -391,6 +399,7 @@ public class Email { messageBodyPart.setFileName(attachment.name); multipart.addBodyPart(messageBodyPart); } + message.setContent(multipart); } @@ -475,18 +484,6 @@ public class Email { * throws a MessagingException. */ - /** - * Associate the message with an external Velocity - * {@link org.apache.velocity.Template}. You may also supply a subject - * using {@link #setSubject(java.lang.String)}. - * - * @param templateName simple name to be looked up in the Velocity template - * resources. - */ - public void setTemplate(String templateName) { - template = Velocity.getTemplate(templateName); - } - /** * Test method to send an email to check email server settings * From ff5962cfa6cba8876116d0e8080a12a5e9446976 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Mon, 19 Mar 2018 20:16:08 -0400 Subject: [PATCH 16/39] [DS-3872] Make config visible to introspector; enable testing arbitrary templates; remove more MessageFormat. --- .../src/main/java/org/dspace/core/Email.java | 48 +++++++++++-------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/core/Email.java b/dspace-api/src/main/java/org/dspace/core/Email.java index 505501140f..15ff675805 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -17,7 +17,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.StringWriter; -import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; @@ -356,12 +355,11 @@ public class Email { } } - // Set the subject of the email (may contain parameters) - String fullSubject = MessageFormat.format(subject, arguments.toArray()); + // Set the subject of the email. if (charset != null) { - message.setSubject(fullSubject, charset); + message.setSubject(subject, charset); } else { - message.setSubject(fullSubject); + message.setSubject(subject); } // Add attachments @@ -490,21 +488,30 @@ public class Email { * @param args the command line arguments given */ public static void main(String[] args) { - ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService(); + ConfigurationService config + = DSpaceServicesFactory.getInstance().getConfigurationService(); String to = config.getProperty("mail.admin"); String subject = "DSpace test email"; String server = config.getProperty("mail.server"); String url = config.getProperty("dspace.url"); - Email e = new Email(); - e.setSubject(subject); - e.addRecipient(to); - e.content = "This is a test email sent from DSpace: " + url; - System.out.println("\nAbout to send test email:"); - System.out.println(" - To: " + to); - System.out.println(" - Subject: " + subject); - System.out.println(" - Server: " + server); - boolean disabled = config.getBooleanProperty("mail.server.disabled", false); + Email message; try { + if (args.length <= 0) { + message = new Email(); + message.content = "This is a test email sent from DSpace: " + url; + } else { + message = Email.getEmail(args[0]); + for (int i = 1; i < args.length; i++) { + message.addArgument(args[i]); + } + } + message.setSubject(subject); + message.addRecipient(to); + System.out.println("\nAbout to send test email:"); + System.out.println(" - To: " + to); + System.out.println(" - Subject: " + subject); + System.out.println(" - Server: " + server); + boolean disabled = config.getBooleanProperty("mail.server.disabled", false); if (disabled) { System.err.println("\nError sending email:"); System.err.println(" - Error: cannot test email because mail.server.disabled is set to true"); @@ -513,10 +520,10 @@ public class Email { System.exit(1); return; } - e.send(); - } catch (MessagingException | IOException me) { + message.send(); + } catch (MessagingException | IOException ex) { System.err.println("\nError sending email:"); - System.err.println(" - Error: " + me); + System.err.format(" - Error: %s%n", ex); System.err.println("\nPlease see the DSpace documentation for assistance.\n"); System.err.println("\n"); System.exit(1); @@ -598,9 +605,10 @@ public class Email { } /** - * Wrap ConfigurationService to prevent templates from modifying the configuration. + * Wrap ConfigurationService to prevent templates from modifying + * the configuration. */ - private class UnmodifiableConfigurationService { + public class UnmodifiableConfigurationService { private final ConfigurationService configurationService; /** From 62acad25a342ba2264ba2b75f0ac33cc37feba01 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 22 May 2019 12:10:14 -0400 Subject: [PATCH 17/39] [DS-3872] Add many inexplicably missing imports after rebase. --- .../main/java/org/dspace/app/rest/Application.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java index b1a1a8bd7c..c82de17efe 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java @@ -7,7 +7,10 @@ */ package org.dspace.app.rest; +import java.io.File; import java.util.List; +import javax.naming.Context; +import javax.naming.InitialContext; import javax.servlet.Filter; import org.dspace.app.rest.filter.DSpaceRequestContextFilter; @@ -17,6 +20,11 @@ import org.dspace.app.rest.utils.ApplicationConfig; import org.dspace.app.rest.utils.DSpaceConfigurationInitializer; import org.dspace.app.rest.utils.DSpaceKernelInitializer; import org.dspace.app.util.DSpaceContextListener; +import org.dspace.kernel.DSpaceKernel; +import org.dspace.kernel.DSpaceKernelManager; +import org.dspace.servicemanager.DSpaceKernelImpl; +import org.dspace.servicemanager.DSpaceKernelInit; +import org.dspace.servicemanager.config.DSpaceConfigurationService; import org.dspace.utils.servlet.DSpaceWebappServletFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,7 +33,11 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.velocity.VelocityAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ApplicationListener; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; +import org.springframework.context.event.ContextClosedEvent; import org.springframework.core.annotation.Order; import org.springframework.hateoas.RelProvider; import org.springframework.web.context.request.RequestContextListener; From 17daf04f21eb8155b999b0377f48ed95dcba92ab Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 22 May 2019 13:45:16 -0400 Subject: [PATCH 18/39] [DS-3872] Re-remove factored-out code that was un-removed by a botched rebase. --- .../java/org/dspace/app/rest/Application.java | 104 ------------------ 1 file changed, 104 deletions(-) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java index c82de17efe..2b37ce14ce 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java @@ -7,10 +7,7 @@ */ package org.dspace.app.rest; -import java.io.File; import java.util.List; -import javax.naming.Context; -import javax.naming.InitialContext; import javax.servlet.Filter; import org.dspace.app.rest.filter.DSpaceRequestContextFilter; @@ -20,11 +17,6 @@ import org.dspace.app.rest.utils.ApplicationConfig; import org.dspace.app.rest.utils.DSpaceConfigurationInitializer; import org.dspace.app.rest.utils.DSpaceKernelInitializer; import org.dspace.app.util.DSpaceContextListener; -import org.dspace.kernel.DSpaceKernel; -import org.dspace.kernel.DSpaceKernelManager; -import org.dspace.servicemanager.DSpaceKernelImpl; -import org.dspace.servicemanager.DSpaceKernelInit; -import org.dspace.servicemanager.config.DSpaceConfigurationService; import org.dspace.utils.servlet.DSpaceWebappServletFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,11 +25,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.velocity.VelocityAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; -import org.springframework.context.event.ContextClosedEvent; import org.springframework.core.annotation.Order; import org.springframework.hateoas.RelProvider; import org.springframework.web.context.request.RequestContextListener; @@ -156,96 +144,4 @@ public class Application extends SpringBootServletInitializer { } }; } - - /** - * Utility class that will destroy the DSpace Kernel on Spring Boot shutdown - */ - private class DSpaceKernelDestroyer implements ApplicationListener { - private DSpaceKernel kernel; - - public DSpaceKernelDestroyer(DSpaceKernel kernel) { - this.kernel = kernel; - } - - public void onApplicationEvent(final ContextClosedEvent event) { - if (this.kernel != null) { - this.kernel.destroy(); - this.kernel = null; - } - } - } - - /** - * Utility class that will initialize the DSpace Kernel on Spring Boot startup - */ - private class DSpaceKernelInitializer implements ApplicationContextInitializer { - - private transient DSpaceKernel dspaceKernel; - - public void initialize(final ConfigurableApplicationContext applicationContext) { - - String dspaceHome = applicationContext.getEnvironment().getProperty("dspace.dir"); - - this.dspaceKernel = DSpaceKernelManager.getDefaultKernel(); - if (this.dspaceKernel == null) { - DSpaceKernelImpl kernelImpl = null; - try { - kernelImpl = DSpaceKernelInit.getKernel(null); - if (!kernelImpl.isRunning()) { - kernelImpl.start(getProvidedHome(dspaceHome)); // init the kernel - } - this.dspaceKernel = kernelImpl; - - } catch (Exception e) { - // failed to start so destroy it and log and throw an exception - try { - if (kernelImpl != null) { - kernelImpl.destroy(); - } - this.dspaceKernel = null; - } catch (Exception e1) { - // nothing - } - String message = "Failure during ServletContext initialisation: " + e.getMessage(); - log.error(message, e); - throw new RuntimeException(message, e); - } - } - - if (applicationContext.getParent() == null) { - //Set the DSpace Kernel Application context as a parent of the Spring Boot context so that - //we can auto-wire all DSpace Kernel services - applicationContext.setParent(dspaceKernel.getServiceManager().getApplicationContext()); - - //Add a listener for Spring Boot application shutdown so that we can nicely cleanup the DSpace kernel. - applicationContext.addApplicationListener(new DSpaceKernelDestroyer(dspaceKernel)); - } - } - - /** - * Find DSpace's "home" directory. - * Initially look for JNDI Resource called "java:/comp/env/dspace.dir". - * If not found, look for "dspace.dir" initial context parameter. - */ - private String getProvidedHome(String dspaceHome) { - String providedHome = null; - try { - Context ctx = new InitialContext(); - providedHome = (String) ctx.lookup("java:/comp/env/" + DSpaceConfigurationService.DSPACE_HOME); - } catch (Exception e) { - // do nothing - } - - if (providedHome == null) { - if (dspaceHome != null && !dspaceHome.equals("") && - !dspaceHome.equals("${" + DSpaceConfigurationService.DSPACE_HOME + "}")) { - File test = new File(dspaceHome); - if (test.exists() && new File(test, DSpaceConfigurationService.DSPACE_CONFIG_PATH).exists()) { - providedHome = dspaceHome; - } - } - } - return providedHome; - } - } } From e3ac8f98b11045695e6fd0875e3f687bfe3702dd Mon Sep 17 00:00:00 2001 From: Marie Verdonck Date: Wed, 29 May 2019 14:36:21 +0200 Subject: [PATCH 19/39] Full CRUD on bitstreamformat registry endpoint; added: POST /api/core/bitstreamformats PUT /api/core/bitstreamformats/<:id> DELETE /api/core/bitstreamformats/<:id> Signed-off-by: Marie Verdonck --- .../content/BitstreamFormatServiceImpl.java | 4 + .../service/BitstreamFormatService.java | 7 ++ .../converter/BitstreamFormatConverter.java | 16 ++- .../app/rest/model/BitstreamFormatRest.java | 10 +- .../BitstreamFormatRestRepository.java | 116 +++++++++++++++++- 5 files changed, 143 insertions(+), 10 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/BitstreamFormatServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/BitstreamFormatServiceImpl.java index 7239424d91..1051b79757 100644 --- a/dspace-api/src/main/java/org/dspace/content/BitstreamFormatServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/BitstreamFormatServiceImpl.java @@ -234,6 +234,10 @@ public class BitstreamFormatServiceImpl implements BitstreamFormatService { return -1; } + public String getSupportLevelString(int id) { + return supportLevelText[id]; + } + @Override public BitstreamFormat guessFormat(Context context, Bitstream bitstream) throws SQLException { String filename = bitstream.getName(); diff --git a/dspace-api/src/main/java/org/dspace/content/service/BitstreamFormatService.java b/dspace-api/src/main/java/org/dspace/content/service/BitstreamFormatService.java index 19ef5c7d07..a464885629 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/BitstreamFormatService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/BitstreamFormatService.java @@ -118,6 +118,13 @@ public interface BitstreamFormatService extends DSpaceCRUDService { + + @Autowired + BitstreamFormatService bitstreamFormatService; + @Override public BitstreamFormatRest fromModel(BitstreamFormat obj) { BitstreamFormatRest bf = new BitstreamFormatRest(); - bf.setDescription(obj.getDescription()); - bf.setExtensions(bf.getExtensions()); bf.setId(obj.getID()); - bf.setMimetype(obj.getMIMEType()); bf.setShortDescription(obj.getShortDescription()); + bf.setDescription(obj.getDescription()); + bf.setMimetype(obj.getMIMEType()); bf.setInternal(obj.isInternal()); + bf.setSupportLevel(bitstreamFormatService.getSupportLevelString(obj.getSupportLevel())); + bf.setExtensions(obj.getExtensions()); return bf; } @Override public BitstreamFormat toModel(BitstreamFormatRest obj) { // TODO Auto-generated method stub + //Creation of BitstreamFormats protected by bitstreamFormatService, which requires context (not all users are + // authorized to create new BitstreamFormats), not sure if logic for that should be here; + // currently in BitstreamFormatRestRepository return null; } } diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java index f3241195c4..8f01eadeff 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java @@ -10,7 +10,9 @@ package org.dspace.app.rest.model; import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import org.dspace.app.rest.RestResourceController; +import org.dspace.app.rest.exception.UnprocessableEntityException; /** * The BitstreamFormat REST Resource @@ -28,7 +30,7 @@ public class BitstreamFormatRest extends BaseObjectRest { private String mimetype; - private int supportLevel; + private String supportLevel; private boolean internal; @@ -58,11 +60,11 @@ public class BitstreamFormatRest extends BaseObjectRest { this.mimetype = mimetype; } - public int getSupportLevel() { + public String getSupportLevel() { return supportLevel; } - public void setSupportLevel(int supportLevel) { + public void setSupportLevel(String supportLevel) { this.supportLevel = supportLevel; } @@ -82,6 +84,7 @@ public class BitstreamFormatRest extends BaseObjectRest { this.extensions = extensions; } + @JsonIgnore @Override public String getCategory() { @@ -89,6 +92,7 @@ public class BitstreamFormatRest extends BaseObjectRest { } @Override + @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getType() { return NAME; } diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java index ef942e64f2..3d26aeaa09 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java @@ -2,25 +2,36 @@ * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at - * + *

* http://www.dspace.org/license/ */ package org.dspace.app.rest.repository; +import java.io.IOException; import java.sql.SQLException; import java.util.List; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.dspace.app.rest.converter.BitstreamFormatConverter; +import org.dspace.app.rest.converter.MetadataConverter; +import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.BitstreamFormatRest; import org.dspace.app.rest.model.hateoas.BitstreamFormatResource; +import org.dspace.authorize.AuthorizeException; import org.dspace.content.BitstreamFormat; import org.dspace.content.service.BitstreamFormatService; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; + /** * This is the repository responsible to manage BitstreamFormat Rest object @@ -31,11 +42,14 @@ import org.springframework.stereotype.Component; public class BitstreamFormatRestRepository extends DSpaceRestRepository { @Autowired - BitstreamFormatService bfs; + BitstreamFormatService bitstreamFormatService; @Autowired BitstreamFormatConverter converter; + @Autowired + MetadataConverter metadataConverter; + public BitstreamFormatRestRepository() { System.out.println("Repository initialized by Spring"); } @@ -44,7 +58,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { List bit = null; try { - bit = bfs.findAll(context); + bit = bitstreamFormatService.findAll(context); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } @@ -66,6 +80,100 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository Date: Fri, 31 May 2019 14:49:12 +0200 Subject: [PATCH 22/39] unused import, checkstyle violation --- .../java/org/dspace/app/rest/model/BitstreamFormatRest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java index 8f01eadeff..c56963c685 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java @@ -7,12 +7,12 @@ */ package org.dspace.app.rest.model; +import org.dspace.app.rest.RestResourceController; + import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import org.dspace.app.rest.RestResourceController; -import org.dspace.app.rest.exception.UnprocessableEntityException; /** * The BitstreamFormat REST Resource From 44f8a8ef9f89acd9dd67e6985d2159854368c188 Mon Sep 17 00:00:00 2001 From: Marie Verdonck Date: Fri, 31 May 2019 14:49:59 +0200 Subject: [PATCH 23/39] Thown sql exception with message & checkstyle --- .../BitstreamFormatRestRepository.java | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java index 3d26aeaa09..b4105578d9 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java @@ -2,26 +2,32 @@ * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at - *

+ * * http://www.dspace.org/license/ */ package org.dspace.app.rest.repository; -import java.io.IOException; -import java.sql.SQLException; -import java.util.List; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.dspace.app.rest.converter.BitstreamFormatConverter; import org.dspace.app.rest.converter.MetadataConverter; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.BitstreamFormatRest; import org.dspace.app.rest.model.hateoas.BitstreamFormatResource; + import org.dspace.authorize.AuthorizeException; import org.dspace.content.BitstreamFormat; import org.dspace.content.service.BitstreamFormatService; import org.dspace.core.Context; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -29,9 +35,6 @@ import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; - /** * This is the repository responsible to manage BitstreamFormat Rest object @@ -96,11 +99,11 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository map = mapper.readValue(content, Map.class); + String newlyCreatedBitstreamID = String.valueOf(map.get("id")); + //Verify creation + getClient().perform(get("/api/core/bitstreamformats/" + newlyCreatedBitstreamID)) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.description", is(bitstreamFormatRest.getDescription()))) + .andExpect(jsonPath("$.mimetype", is(bitstreamFormatRest.getMimetype()))) + .andExpect(jsonPath("$.type", is("bitstreamformat"))) + .andExpect(jsonPath("$._links.self.href", startsWith(REST_SERVER_URL))) + .andExpect(jsonPath("$._links.self.href", + endsWith("/api/core/bitstreamformats/" + newlyCreatedBitstreamID))); + } + + @Test + public void createNoAccess() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + BitstreamFormatRest bitstreamFormatRest = this.createRandomMockBitstreamRest(false); + + //Try to create bitstreamFormat without auth token + getClient(null).perform(post("/api/core/bitstreamformats/") + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isUnauthorized()); + } + + @Test + public void createNonAdminAccess() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + BitstreamFormatRest bitstreamFormatRest = this.createRandomMockBitstreamRest(false); + context.turnOffAuthorisationSystem(); + EPerson user = EPersonBuilder.createEPerson(context) + .withNameInMetadata("first", "last") + .withEmail("testaze@gmail.com") + .withPassword(password) + .withLanguage(I18nUtil.getDefaultLocale().getLanguage()) + .build(); + context.restoreAuthSystemState(); + //Try to create bitstreamFormat with non-admin auth token + String token = getAuthToken(user.getEmail(), password); + getClient(token).perform(post("/api/core/bitstreamformats/") + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isForbidden()); + } + + @Test + public void createAlreadyExisting() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + BitstreamFormatRest bitstreamFormatRest = this.createRandomMockBitstreamRest(true); + //Try to create same bitstream twice + String token = getAuthToken(admin.getEmail(), password); + getClient(token).perform(post("/api/core/bitstreamformats/") + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isCreated()); + //Second time it fails + getClient(token).perform(post("/api/core/bitstreamformats/") + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isInternalServerError()); + } + + @Test + public void updateAdminAccess() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateAdminAccess") + .build(); + context.restoreAuthSystemState(); + + BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + String token = getAuthToken(admin.getEmail(), password); + //Update it + bitstreamFormatRest.setShortDescription("Test short UPDATED"); + getClient(token).perform(put("/api/core/bitstreamformats/" + bitstreamFormat.getID()) + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isOk()); + + //Verify change + getClient().perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.description", is(bitstreamFormatRest.getDescription()))) + .andExpect(jsonPath("$.mimetype", is(bitstreamFormatRest.getMimetype()))) + .andExpect(jsonPath("$.type", is("bitstreamformat"))) + .andExpect(jsonPath("$._links.self.href", startsWith(REST_SERVER_URL))) + .andExpect(jsonPath("$._links.self.href", + endsWith("/api/core/bitstreamformats/" + bitstreamFormat.getID()))); + } + + @Test + public void updateNonExistingIDInURLAndJSON() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateNonExistingIDInURLAndJSON") + .build(); + context.restoreAuthSystemState(); + + int nonExistentBitstreamFormatID = 404404404; + + BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + String token = getAuthToken(admin.getEmail(), password); + //Update it with non existent ID in URL and in JSON + bitstreamFormatRest.setShortDescription("Test short UPDATED"); + bitstreamFormatRest.setId(nonExistentBitstreamFormatID); + getClient(token).perform(put("/api/core/bitstreamformats/" + nonExistentBitstreamFormatID) + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isNotFound()); + } + + @Test + public void updateNonExistingIDInJustURL() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateNonExistingIDInJustURL") + .build(); + context.restoreAuthSystemState(); + + int nonExistentBitstreamFormatID = 404404404; + + BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + String token = getAuthToken(admin.getEmail(), password); + //Update it with non existent ID in URL + bitstreamFormatRest.setShortDescription("Test short UPDATED"); + getClient(token).perform(put("/api/core/bitstreamformats/" + nonExistentBitstreamFormatID) + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isNotFound()); + } + + @Test + public void updateNonExistingIDInJSONButValidInURL() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateNonExistingIDInJSONButValidInURL") + .build(); + context.restoreAuthSystemState(); + + int nonExistentBitstreamFormatID = 404404404; + + BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + String token = getAuthToken(admin.getEmail(), password); + //Update it with non existent ID in JSON, but valid in URL + bitstreamFormatRest.setShortDescription("Test short UPDATED"); + bitstreamFormatRest.setId(nonExistentBitstreamFormatID); + getClient(token).perform(put("/api/core/bitstreamformats/" + bitstreamFormat.getID()) + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isBadRequest()); + } + + @Test + public void updateNotMatchingIDsInJSONAndURL() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat1 = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateNotMatchingIDsInJSONAndURL 1") + .build(); + BitstreamFormat bitstreamFormat2 = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateNotMatchingIDsInJSONAndURL 2") + .build(); + context.restoreAuthSystemState(); + + BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat1); + String token = getAuthToken(admin.getEmail(), password); + //Update but id in body is not same id as in URL + bitstreamFormatRest.setShortDescription("Test short UPDATED"); + bitstreamFormatRest.setId(bitstreamFormat2.getID()); + getClient(token).perform(put("/api/core/bitstreamformats/" + bitstreamFormat1.getID()) + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isBadRequest()); + } + + @Test + public void updateNoAccess() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateNoAccess") + .build(); + context.restoreAuthSystemState(); + + BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + + //Try to update bitstreamFormat without auth token + bitstreamFormatRest.setShortDescription("Test short UPDATED"); + getClient(null).perform(put("/api/core/bitstreamformats/" + bitstreamFormat.getID()) + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isUnauthorized()); + } + + @Test + public void updateNonAdminAccess() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateNonAdminAccess") + .build(); + EPerson user = EPersonBuilder.createEPerson(context) + .withNameInMetadata("first", "last") + .withEmail("testaze@gmail.com") + .withPassword(password) + .withLanguage(I18nUtil.getDefaultLocale().getLanguage()) + .build(); + context.restoreAuthSystemState(); + + BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); + String token = getAuthToken(user.getEmail(), password); + + //Try to update bitstreamFormat without non-admin auth token + bitstreamFormatRest.setShortDescription("Test short UPDATED"); + getClient(token).perform(put("/api/core/bitstreamformats/" + bitstreamFormat.getID()) + .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) + .andExpect(status().isForbidden()); + } + + @Test + public void deleteAdminAccess() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateAdminAccess") + .build(); + context.restoreAuthSystemState(); + + String token = getAuthToken(admin.getEmail(), password); + //Delete it + getClient(token).perform(delete("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isNoContent()); + + //Verify deleted + getClient().perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isNotFound()); + } + + @Test + public void deleteNonExistingID() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateAdminAccess") + .build(); + context.restoreAuthSystemState(); + + String nonExistentID = "404404404"; + + String token = getAuthToken(admin.getEmail(), password); + //Delete it + getClient(token).perform(delete("/api/core/bitstreamformats/" + nonExistentID)) + .andExpect(status().isNotFound()); + } + + @Test + public void deleteNoAccess() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateAdminAccess") + .build(); + context.restoreAuthSystemState(); + + //Delete it + getClient(null).perform(delete("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isUnauthorized()); + } + + @Test + public void deleteNonAdminAccess() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + //Create bitstream format + context.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + .withMimeType("application/octet-stream") + .withDescription("Description - updateAdminAccess") + .build(); + EPerson user = EPersonBuilder.createEPerson(context) + .withNameInMetadata("first", "last") + .withEmail("testaze@gmail.com") + .withPassword(password) + .withLanguage(I18nUtil.getDefaultLocale().getLanguage()) + .build(); + context.restoreAuthSystemState(); + + //Delete it + String token = getAuthToken(user.getEmail(), password); + getClient(token).perform(delete("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isForbidden()); + } + + private BitstreamFormatRest createRandomMockBitstreamRest(boolean withRand) { + BitstreamFormatRest bitstreamFormatRest = new BitstreamFormatRest(); + String random = null; + if (withRand) { + Random rand = new Random(); + random = String.valueOf(rand.nextInt(100) + 1); + } + bitstreamFormatRest.setShortDescription("Test short" + random); + bitstreamFormatRest.setDescription("Full description of Test short"); + bitstreamFormatRest.setMimetype("text/plain"); + bitstreamFormatRest.setSupportLevel("KNOWN"); + bitstreamFormatRest.setInternal(false); + bitstreamFormatRest.setExtensions(Arrays.asList("txt", "asc")); + return bitstreamFormatRest; } } From d6b5abd694aa0872785cd29747d2ec03939a0cf7 Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Fri, 12 Apr 2019 14:48:25 +0200 Subject: [PATCH 25/39] [DS-4217] applied the name refactor and rewrote BadRequestException to use this class instead Signed-off-by: Marie Verdonck --- .../dspace/app/rest/RestResourceController.java | 4 ++-- ...ption.java => DSpaceBadRequestException.java} | 11 ++++------- .../repository/CollectionRestRepository.java | 6 +++--- .../rest/repository/CommunityRestRepository.java | 4 ++-- .../rest/repository/DSpaceRestRepository.java | 8 ++++---- .../app/rest/repository/ItemRestRepository.java | 6 +++--- .../repository/MetadataFieldRestRepository.java | 4 ++-- .../repository/MetadataSchemaRestRepository.java | 4 ++-- .../repository/WorkflowItemRestRepository.java | 6 +++--- .../repository/WorkspaceItemRestRepository.java | 6 +++--- .../repository/patch/AbstractResourcePatch.java | 16 ++++++++-------- .../app/rest/repository/patch/EPersonPatch.java | 4 ++-- .../app/rest/repository/patch/ItemPatch.java | 4 ++-- .../patch/factories/EPersonOperationFactory.java | 6 +++--- .../patch/factories/ItemOperationFactory.java | 6 +++--- .../impl/EPersonCertificateReplaceOperation.java | 4 ++-- .../impl/EPersonLoginReplaceOperation.java | 4 ++-- .../impl/EPersonNetidReplaceOperation.java | 4 ++-- .../impl/ItemDiscoverableReplaceOperation.java | 4 ++-- .../impl/ItemWithdrawReplaceOperation.java | 4 ++-- .../patch/factories/impl/PatchOperation.java | 11 ++++++----- .../factories/impl/ReplacePatchOperation.java | 8 ++++---- .../factories/impl/ResourcePatchOperation.java | 4 ++-- 23 files changed, 68 insertions(+), 70 deletions(-) rename dspace-spring-rest/src/main/java/org/dspace/app/rest/exception/{PatchBadRequestException.java => DSpaceBadRequestException.java} (55%) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/RestResourceController.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/RestResourceController.java index 0d932690cd..1a359947aa 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/RestResourceController.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/RestResourceController.java @@ -31,8 +31,8 @@ import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.atteo.evo.inflector.English; import org.dspace.app.rest.converter.JsonPatchConverter; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.PaginationException; -import org.dspace.app.rest.exception.PatchBadRequestException; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.RepositoryNotFoundException; import org.dspace.app.rest.exception.RepositorySearchMethodNotFoundException; @@ -729,7 +729,7 @@ public class RestResourceController implements InitializingBean { Patch patch = patchConverter.convert(jsonNode); modelObject = repository.patch(request, apiCategory, model, id, patch); } catch (RepositoryMethodNotImplementedException | UnprocessableEntityException | - PatchBadRequestException | ResourceNotFoundException e) { + DSpaceBadRequestException | ResourceNotFoundException e) { log.error(e.getMessage(), e); throw e; } diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/exception/PatchBadRequestException.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/exception/DSpaceBadRequestException.java similarity index 55% rename from dspace-spring-rest/src/main/java/org/dspace/app/rest/exception/PatchBadRequestException.java rename to dspace-spring-rest/src/main/java/org/dspace/app/rest/exception/DSpaceBadRequestException.java index 2000684fb2..4bf6fbc61b 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/exception/PatchBadRequestException.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/exception/DSpaceBadRequestException.java @@ -11,21 +11,18 @@ import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; /** - * Malformed patch document (taken from rfc5789#section-2.2) - When the server - * determines that the patch document provided by the client is not properly - * formatted, it SHOULD return a 400 (Bad Request) response. The definition of - * badly formatted depends on the patch document chosen. + * When a request is malformed, we use this exception to indicate this to the client * * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) */ @ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "Bad Request") -public class PatchBadRequestException extends RuntimeException { +public class DSpaceBadRequestException extends RuntimeException { - public PatchBadRequestException(String message) { + public DSpaceBadRequestException(String message) { this(message, null); } - public PatchBadRequestException(String message, Exception e) { + public DSpaceBadRequestException(String message, Exception e) { super(message, e); } } diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java index a7ba1a5552..cceb32b546 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java @@ -14,7 +14,6 @@ import java.util.List; import java.util.UUID; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.BadRequestException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -23,6 +22,7 @@ import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.converter.CollectionConverter; import org.dspace.app.rest.converter.MetadataConverter; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.CollectionRest; @@ -191,7 +191,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository!"); diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java index 6f2c4e8179..7c783da007 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java @@ -26,7 +26,7 @@ import org.apache.logging.log4j.Logger; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.converter.WorkspaceItemConverter; -import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.model.ErrorRest; import org.dspace.app.rest.model.WorkspaceItemRest; import org.dspace.app.rest.model.hateoas.WorkspaceItemResource; @@ -280,7 +280,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository!"); diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/AbstractResourcePatch.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/AbstractResourcePatch.java index 547e33842d..0a3b272d68 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/AbstractResourcePatch.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/AbstractResourcePatch.java @@ -9,7 +9,7 @@ package org.dspace.app.rest.repository.patch; import java.util.List; -import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.patch.Operation; @@ -28,7 +28,7 @@ public abstract class AbstractResourcePatch { * @param restModel the rest resource to patch * @param operations list of patch operations * @throws UnprocessableEntityException - * @throws PatchBadRequestException + * @throws DSpaceBadRequestException */ public R patch(R restModel, List operations) { @@ -53,7 +53,7 @@ public abstract class AbstractResourcePatch { continue ops; default: // JsonPatchConverter should have thrown error before this point. - throw new PatchBadRequestException("Missing or illegal patch operation: " + op.getOp()); + throw new DSpaceBadRequestException("Missing or illegal patch operation: " + op.getOp()); } } @@ -63,14 +63,14 @@ public abstract class AbstractResourcePatch { // The default patch methods throw an error when no sub-class implementation is provided. protected R add(R restModel, Operation operation) - throws UnprocessableEntityException, PatchBadRequestException { + throws UnprocessableEntityException, DSpaceBadRequestException { throw new UnprocessableEntityException( "The add operation is not supported." ); } protected R replace(R restModel, Operation operation) - throws UnprocessableEntityException, PatchBadRequestException { + throws UnprocessableEntityException, DSpaceBadRequestException { throw new UnprocessableEntityException( "The replace operation is not supported." ); @@ -78,21 +78,21 @@ public abstract class AbstractResourcePatch { protected R remove(R restModel, Operation operation) - throws UnprocessableEntityException, PatchBadRequestException { + throws UnprocessableEntityException, DSpaceBadRequestException { throw new UnprocessableEntityException( "The remove operation is not supported." ); } protected R copy(R restModel, Operation operation) - throws UnprocessableEntityException, PatchBadRequestException { + throws UnprocessableEntityException, DSpaceBadRequestException { throw new UnprocessableEntityException( "The copy operation is not supported." ); } protected R move(R restModel, Operation operation) - throws UnprocessableEntityException, PatchBadRequestException { + throws UnprocessableEntityException, DSpaceBadRequestException { throw new UnprocessableEntityException( "The move operation is not supported." ); diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/EPersonPatch.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/EPersonPatch.java index 5c7738eb0e..36abde2fcc 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/EPersonPatch.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/EPersonPatch.java @@ -7,7 +7,7 @@ */ package org.dspace.app.rest.repository.patch; -import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.model.patch.Operation; @@ -32,7 +32,7 @@ public class EPersonPatch extends DSpaceObjectPatch { * @param eperson the eperson rest representation * @param operation the replace operation * @throws UnprocessableEntityException - * @throws PatchBadRequestException + * @throws DSpaceBadRequestException */ protected EPersonRest replace(EPersonRest eperson, Operation operation) { ResourcePatchOperation patchOperation = diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/ItemPatch.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/ItemPatch.java index cc8a331f62..fa652e9616 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/ItemPatch.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/ItemPatch.java @@ -7,7 +7,7 @@ */ package org.dspace.app.rest.repository.patch; -import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.patch.Operation; @@ -32,7 +32,7 @@ public class ItemPatch extends DSpaceObjectPatch { * @param item the rest representation of the item * @param operation the replace operation * @throws UnprocessableEntityException - * @throws PatchBadRequestException + * @throws DSpaceBadRequestException */ protected ItemRest replace(ItemRest item, Operation operation) { diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/EPersonOperationFactory.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/EPersonOperationFactory.java index c979a4f953..d556634188 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/EPersonOperationFactory.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/EPersonOperationFactory.java @@ -7,7 +7,7 @@ */ package org.dspace.app.rest.repository.patch.factories; -import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.repository.patch.factories.impl.EPersonCertificateReplaceOperation; import org.dspace.app.rest.repository.patch.factories.impl.EPersonEmailReplaceOperation; @@ -51,7 +51,7 @@ public class EPersonOperationFactory { * * @param path the operation path * @return the patch operation implementation - * @throws PatchBadRequestException + * @throws DSpaceBadRequestException */ public ResourcePatchOperation getReplaceOperationForPath(String path) { @@ -67,7 +67,7 @@ public class EPersonOperationFactory { case OPERATION_SET_EMAIL: return emailReplaceOperation; default: - throw new PatchBadRequestException("Missing patch operation for: " + path); + throw new DSpaceBadRequestException("Missing patch operation for: " + path); } } diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/ItemOperationFactory.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/ItemOperationFactory.java index 3360e85036..8a37ced711 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/ItemOperationFactory.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/ItemOperationFactory.java @@ -7,7 +7,7 @@ */ package org.dspace.app.rest.repository.patch.factories; -import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.repository.patch.factories.impl.ItemDiscoverableReplaceOperation; import org.dspace.app.rest.repository.patch.factories.impl.ItemWithdrawReplaceOperation; @@ -37,7 +37,7 @@ public class ItemOperationFactory { * * @param path the operation path * @return the patch operation implementation - * @throws PatchBadRequestException + * @throws DSpaceBadRequestException */ public ResourcePatchOperation getReplaceOperationForPath(String path) { @@ -47,7 +47,7 @@ public class ItemOperationFactory { case OPERATION_PATH_WITHDRAW: return itemWithdrawReplaceOperation; default: - throw new PatchBadRequestException("Missing patch operation for: " + path); + throw new DSpaceBadRequestException("Missing patch operation for: " + path); } } } diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonCertificateReplaceOperation.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonCertificateReplaceOperation.java index 1ab27d57cc..66e8b117f7 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonCertificateReplaceOperation.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonCertificateReplaceOperation.java @@ -7,7 +7,7 @@ */ package org.dspace.app.rest.repository.patch.factories.impl; -import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.model.patch.Operation; import org.springframework.stereotype.Component; @@ -42,7 +42,7 @@ public class EPersonCertificateReplaceOperation extends ReplacePatchOperation * @param resource the rest model. * @param operation the patch operation. * @return the updated rest model. - * @throws PatchBadRequestException + * @throws DSpaceBadRequestException */ public abstract R perform(R resource, Operation operation); @@ -37,7 +37,7 @@ public abstract class PatchOperation */ void checkOperationValue(Object value) { if (value == null) { - throw new PatchBadRequestException("No value provided for the operation."); + throw new DSpaceBadRequestException("No value provided for the operation."); } } @@ -46,7 +46,7 @@ public abstract class PatchOperation * * @param value the operation value * @return the original or derived boolean value - * @throws PatchBadRequestException + * @throws DSpaceBadRequestException */ Boolean getBooleanOperationValue(Object value) { Boolean bool; @@ -54,7 +54,8 @@ public abstract class PatchOperation if (value instanceof String) { bool = BooleanUtils.toBooleanObject((String) value); if (bool == null) { - throw new PatchBadRequestException("Boolean value not provided."); + // make sure the string was converted to boolean. + throw new DSpaceBadRequestException("Boolean value not provided."); } } else { bool = (Boolean) value; diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ReplacePatchOperation.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ReplacePatchOperation.java index f7c441918b..3205c7019f 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ReplacePatchOperation.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ReplacePatchOperation.java @@ -7,7 +7,7 @@ */ package org.dspace.app.rest.repository.patch.factories.impl; -import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.patch.Operation; @@ -29,7 +29,7 @@ public abstract class ReplacePatchOperation * @param resource the rest model. * @param operation the replace patch operation. * @return the updated rest model. - * @throws PatchBadRequestException + * @throws DSpaceBadRequestException * @throws UnprocessableEntityException */ @Override @@ -47,7 +47,7 @@ public abstract class ReplacePatchOperation * @param resource the rest model. * @param operation the replace patch operation. * @return the updated rest model. - * @throws PatchBadRequestException + * @throws DSpaceBadRequestException * @throws UnprocessableEntityException */ abstract R replace(R resource, Operation operation); @@ -59,7 +59,7 @@ public abstract class ReplacePatchOperation * to assure that the replace operation acts only on an existing value. * * @param resource the rest model. - * @throws PatchBadRequestException + * @throws DSpaceBadRequestException */ abstract void checkModelForExistingValue(R resource, Operation operation); diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ResourcePatchOperation.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ResourcePatchOperation.java index dc531b40fe..9409328fba 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ResourcePatchOperation.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ResourcePatchOperation.java @@ -7,7 +7,7 @@ */ package org.dspace.app.rest.repository.patch.factories.impl; -import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.patch.Operation; @@ -18,6 +18,6 @@ import org.dspace.app.rest.model.patch.Operation; public interface ResourcePatchOperation { R perform(R resource, Operation operation) - throws PatchBadRequestException; + throws DSpaceBadRequestException; } From db8f203f015dea92e658152c604ae5d74c7e4c6c Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Tue, 14 May 2019 09:01:12 +0200 Subject: [PATCH 26/39] [DS-4217] fixed compilation failure after rebase and wrote tests for the DSpaceBadRequestException Signed-off-by: Marie Verdonck --- .../impl/EPersonEmailReplaceOperation.java | 4 +- .../app/rest/CollectionRestRepositoryIT.java | 76 +++++++++++++++++++ .../app/rest/CommunityRestRepositoryIT.java | 41 ++++++++++ .../dspace/app/rest/ItemRestRepositoryIT.java | 76 +++++++++++++++++++ 4 files changed, 195 insertions(+), 2 deletions(-) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonEmailReplaceOperation.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonEmailReplaceOperation.java index 9651e893a8..9907361e4e 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonEmailReplaceOperation.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonEmailReplaceOperation.java @@ -7,7 +7,7 @@ */ package org.dspace.app.rest.repository.patch.factories.impl; -import org.dspace.app.rest.exception.PatchBadRequestException; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.model.patch.Operation; import org.springframework.stereotype.Component; @@ -36,7 +36,7 @@ public class EPersonEmailReplaceOperation extends ReplacePatchOperationSome cool HTML code here

")) + .put("dc.description.abstract", + new MetadataValueRest("top-level community created via the REST API")) + .put("dc.description.tableofcontents", + new MetadataValueRest("

HTML News

")) + .put("dc.rights", + new MetadataValueRest("Custom Copyright Text")) + .put("dc.title", + new MetadataValueRest("Title Text"))); + + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform(post("/api/core/collections") + .content(mapper.writeValueAsBytes(collectionRest)) + .param("parent", "123") + .contentType(contentType)) + .andExpect(status().isBadRequest()); + + } + + + @Test + public void createTestWithoutParentCommunityUUIDBadRequestException() throws Exception { + context.turnOffAuthorisationSystem(); + + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and one collection. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .withLogo("ThisIsSomeDummyText") + .build(); + + ObjectMapper mapper = new ObjectMapper(); + CollectionRest collectionRest = new CollectionRest(); + // We send a name but the created collection should set this to the title + collectionRest.setName("Collection"); + + collectionRest.setMetadata(new MetadataRest() + .put("dc.description", + new MetadataValueRest("

Some cool HTML code here

")) + .put("dc.description.abstract", + new MetadataValueRest("top-level community created via the REST API")) + .put("dc.description.tableofcontents", + new MetadataValueRest("

HTML News

")) + .put("dc.rights", + new MetadataValueRest("Custom Copyright Text")) + .put("dc.title", + new MetadataValueRest("Title Text"))); + + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform(post("/api/core/collections") + .content(mapper.writeValueAsBytes(collectionRest)) + .contentType(contentType)) + .andExpect(status().isBadRequest()); + + } } diff --git a/dspace-spring-rest/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java b/dspace-spring-rest/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java index 3b3c12c720..b83ad7175a 100644 --- a/dspace-spring-rest/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java +++ b/dspace-spring-rest/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java @@ -872,4 +872,45 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest new MetadataPatchSuite().runWith(getClient(token), "/api/core/communities/" + parentCommunity.getID(), expectedStatus); } + + @Test + public void createTestInvalidParentCommunityBadRequest() throws Exception { + context.turnOffAuthorisationSystem(); + + ObjectMapper mapper = new ObjectMapper(); + CommunityRest comm = new CommunityRest(); + // We send a name but the created community should set this to the title + comm.setName("Test Top-Level Community"); + + MetadataRest metadataRest = new MetadataRest(); + + MetadataValueRest description = new MetadataValueRest(); + description.setValue("

Some cool HTML code here

"); + metadataRest.put("dc.description", description); + + MetadataValueRest abs = new MetadataValueRest(); + abs.setValue("Sample top-level community created via the REST API"); + metadataRest.put("dc.description.abstract", abs); + + MetadataValueRest contents = new MetadataValueRest(); + contents.setValue("

HTML News

"); + metadataRest.put("dc.description.tableofcontents", contents); + + MetadataValueRest copyright = new MetadataValueRest(); + copyright.setValue("Custom Copyright Text"); + metadataRest.put("dc.rights", copyright); + + MetadataValueRest title = new MetadataValueRest(); + title.setValue("Title Text"); + metadataRest.put("dc.title", title); + + comm.setMetadata(metadataRest); + + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform(post("/api/core/communities") + .param("parent", "123") + .content(mapper.writeValueAsBytes(comm)) + .contentType(contentType)) + .andExpect(status().isBadRequest()); + } } diff --git a/dspace-spring-rest/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-spring-rest/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index 09e4cd1f0f..4aeb428dd4 100644 --- a/dspace-spring-rest/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-spring-rest/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -1768,4 +1768,80 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { new MetadataPatchSuite().runWith(getClient(token), "/api/core/items/" + item.getID(), expectedStatus); } + @Test + public void testCreateItemInArchiveFalseBadRequestException() throws Exception { + + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + + + ObjectMapper mapper = new ObjectMapper(); + ItemRest itemRest = new ItemRest(); + itemRest.setName("Practices of research data curation in institutional repositories:" + + " A qualitative view from repository staff"); + itemRest.setInArchive(false); + itemRest.setDiscoverable(true); + itemRest.setWithdrawn(false); + + itemRest.setMetadata(new MetadataRest() + .put("dc.description", new MetadataValueRest("

Some cool HTML code here

")) + .put("dc.description.abstract", + new MetadataValueRest("Sample item created via the REST API")) + .put("dc.description.tableofcontents", new MetadataValueRest("

HTML News

")) + .put("dc.rights", new MetadataValueRest("Custom Copyright Text")) + .put("dc.title", new MetadataValueRest("Title Text"))); + + String token = getAuthToken(admin.getEmail(), password); + getClient(token).perform(post("/api/core/items?owningCollection=" + col1.getID().toString()) + .content(mapper.writeValueAsBytes(itemRest)).contentType(contentType)) + .andExpect(status().isBadRequest()); + } + + @Test + public void testCreateItemInvalidCollectionBadRequestException() throws Exception { + + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + + + ObjectMapper mapper = new ObjectMapper(); + ItemRest itemRest = new ItemRest(); + itemRest.setName("Practices of research data curation in institutional repositories:" + + " A qualitative view from repository staff"); + itemRest.setInArchive(false); + itemRest.setDiscoverable(true); + itemRest.setWithdrawn(false); + + itemRest.setMetadata(new MetadataRest() + .put("dc.description", new MetadataValueRest("

Some cool HTML code here

")) + .put("dc.description.abstract", + new MetadataValueRest("Sample item created via the REST API")) + .put("dc.description.tableofcontents", new MetadataValueRest("

HTML News

")) + .put("dc.rights", new MetadataValueRest("Custom Copyright Text")) + .put("dc.title", new MetadataValueRest("Title Text"))); + + String token = getAuthToken(admin.getEmail(), password); + getClient(token).perform(post("/api/core/items?owningCollection=" + parentCommunity.getID().toString()) + .content(mapper.writeValueAsBytes(itemRest)).contentType(contentType)) + .andExpect(status().isBadRequest()); + } + } \ No newline at end of file From 1f40ae51ad0187d1e5133f5cee541bc025e22d93 Mon Sep 17 00:00:00 2001 From: Marie Verdonck Date: Fri, 31 May 2019 15:32:16 +0200 Subject: [PATCH 27/39] 400 - DSpaceBadRequestException when nonvalid supportLevel in rest call for POST /api/core/bitstreamformats PUT /api/core/bitstreamformats/<:id> Implementation & Tests for create/update --- .../BitstreamFormatRestRepository.java | 12 +++++-- .../rest/BitstreamFormatRestRepositoryIT.java | 33 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java index b4105578d9..62d44d4ba7 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java @@ -9,6 +9,7 @@ package org.dspace.app.rest.repository; import org.dspace.app.rest.converter.BitstreamFormatConverter; import org.dspace.app.rest.converter.MetadataConverter; +import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.BitstreamFormatRest; import org.dspace.app.rest.model.hateoas.BitstreamFormatResource; @@ -162,8 +163,12 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository Date: Tue, 4 Jun 2019 13:15:20 +0200 Subject: [PATCH 28/39] Error handling and cleanup: - setAllValuesOfRest() SQLException now meaningful message - metadataConverter never used, so removed - id comparison check flipped so no NullPointer when no id in json in body, but meaningful message --- .../rest/repository/BitstreamFormatRestRepository.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java index 62d44d4ba7..750c37c51f 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java @@ -8,7 +8,6 @@ package org.dspace.app.rest.repository; import org.dspace.app.rest.converter.BitstreamFormatConverter; -import org.dspace.app.rest.converter.MetadataConverter; import org.dspace.app.rest.exception.DSpaceBadRequestException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.BitstreamFormatRest; @@ -51,8 +50,6 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository Date: Wed, 5 Jun 2019 11:46:00 +0200 Subject: [PATCH 29/39] [DS-4266] CRUD support for bitstream formats: Code style cleanup --- .../app/rest/model/BitstreamFormatRest.java | 3 +- .../BitstreamFormatRestRepository.java | 26 +++++++---------- .../rest/BitstreamFormatRestRepositoryIT.java | 29 +++++++++---------- 3 files changed, 26 insertions(+), 32 deletions(-) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java index c56963c685..4d40b20ec1 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java @@ -7,12 +7,11 @@ */ package org.dspace.app.rest.model; -import org.dspace.app.rest.RestResourceController; - import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import org.dspace.app.rest.RestResourceController; /** * The BitstreamFormat REST Resource diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java index 750c37c51f..f93e768943 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java @@ -7,27 +7,23 @@ */ package org.dspace.app.rest.repository; -import org.dspace.app.rest.converter.BitstreamFormatConverter; -import org.dspace.app.rest.exception.DSpaceBadRequestException; -import org.dspace.app.rest.exception.UnprocessableEntityException; -import org.dspace.app.rest.model.BitstreamFormatRest; -import org.dspace.app.rest.model.hateoas.BitstreamFormatResource; - -import org.dspace.authorize.AuthorizeException; -import org.dspace.content.BitstreamFormat; -import org.dspace.content.service.BitstreamFormatService; -import org.dspace.core.Context; - import java.io.IOException; import java.sql.SQLException; import java.util.List; - import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; - +import org.dspace.app.rest.converter.BitstreamFormatConverter; +import org.dspace.app.rest.exception.DSpaceBadRequestException; +import org.dspace.app.rest.exception.UnprocessableEntityException; +import org.dspace.app.rest.model.BitstreamFormatRest; +import org.dspace.app.rest.model.hateoas.BitstreamFormatResource; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.BitstreamFormat; +import org.dspace.content.service.BitstreamFormatService; +import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -166,8 +162,8 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository Date: Wed, 12 Jun 2019 13:04:23 +0200 Subject: [PATCH 30/39] [DS-4266] fixed the lazy loading issue on bitstreamFormat --- .../src/main/java/org/dspace/content/BitstreamFormat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/content/BitstreamFormat.java b/dspace-api/src/main/java/org/dspace/content/BitstreamFormat.java index c1e2a7ec8b..4587e75b44 100644 --- a/dspace-api/src/main/java/org/dspace/content/BitstreamFormat.java +++ b/dspace-api/src/main/java/org/dspace/content/BitstreamFormat.java @@ -71,7 +71,7 @@ public class BitstreamFormat implements Serializable, ReloadableEntity @Column(name = "internal") private boolean internal = false; - @ElementCollection(fetch = FetchType.LAZY) + @ElementCollection(fetch = FetchType.EAGER) @CollectionTable(name = "fileextension", joinColumns = @JoinColumn(name = "bitstream_format_id")) @CollectionId( columns = @Column(name = "file_extension_id"), From 03377c24bd06d37d50a44a9f26c028c8efcdec4c Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Mon, 24 Jun 2019 17:15:41 -0400 Subject: [PATCH 31/39] [DS-3872] Move exlcusion of Spring's Velocity autoconfig to where the others are. --- .../src/main/java/org/dspace/app/rest/Application.java | 2 +- dspace-spring-rest/src/main/resources/application.properties | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java index 2b37ce14ce..41db8dda7d 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java @@ -48,7 +48,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter * @author Andrea Bollini (andrea.bollini at 4science.it) * @author Tim Donohue */ -@SpringBootApplication(exclude = VelocityAutoConfiguration.class) +@SpringBootApplication public class Application extends SpringBootServletInitializer { private static final Logger log = LoggerFactory.getLogger(Application.class); diff --git a/dspace-spring-rest/src/main/resources/application.properties b/dspace-spring-rest/src/main/resources/application.properties index 7a5e5a0193..37883da3ed 100644 --- a/dspace-spring-rest/src/main/resources/application.properties +++ b/dspace-spring-rest/src/main/resources/application.properties @@ -85,12 +85,14 @@ server.error.include-stacktrace = always # * HibernateJpaAutoConfiguration (Hibernate ORM) # * FlywayAutoConfiguration (Flyway migrations) # * SolrAutoConfiguration (Solr) +# * Velocity (email templating) # # TODO: At some point we may want to investigate whether we can re-enable these and remove the custom DSpace init code spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, \ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, \ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, \ - org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration + org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration, \ + org.springframework.boot.autoconfigure.velocity.VelocityAutoConfiguration ######################### # Spring Boot Logging levels From dd84ef0ce636b498ce881ef3217b52cdf8eef693 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Mon, 24 Jun 2019 17:16:52 -0400 Subject: [PATCH 32/39] [DS-3872] More thorough documentation of header control. --- dspace/config/dspace.cfg | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index af11af6ba5..0a9fd60c84 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -163,7 +163,22 @@ mail.allowed.referrers = ${dspace.hostname} # This is especially useful for development and test environments where production data is used when testing functionality. #mail.server.disabled = false -# Message headers which may be set by a message template. +# Message headers which may be set within a message template by assigning values +# to Velocity properties. Only the properties named here will be interpreted as +# header values. In most cases the name of the property will become the +# header's name, and the value of the property, the header's value. +# For example: '#set(My-Header, "Hello World!")' in a template will result in +# the message having a header "My-Header: Hello World!" IFF mail.message.headers +# includes "My-Header". +# +# A few names are special: +# 'subject' supplies the Subject: header's value. +# 'charset' sets the 'charset' parameter of the Content-Type: header of the +# bodypart, when there is a single bodypart. It also causes the +# subject value to be treated as being encoded in this charset. +# If not set, the charset defaults to US-ASCII as specified in RFC 2046. +# If there are multiple bodyparts, all are assumed to be encoded in +# US-ASCII and 'charset' has no effect on them. mail.message.headers = subject mail.message.headers = charset From 5724b2114957d917a834776f7c46edb80093c14e Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Mon, 24 Jun 2019 17:17:42 -0400 Subject: [PATCH 33/39] [DS-3872] Remove outdated, redundant Commons Lang3 dependency. --- pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pom.xml b/pom.xml index e8dcc4bb68..fe79dd3ccc 100644 --- a/pom.xml +++ b/pom.xml @@ -1176,11 +1176,6 @@ commons-lang3 3.7 - - org.apache.commons - commons-lang3 - 3.5 - commons-logging commons-logging From 590d5631974ed087e529369956d9ef56ddbb5261 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Mon, 24 Jun 2019 17:23:18 -0400 Subject: [PATCH 34/39] [DS-3872] Finish removing autoconfigure from Application. --- .../src/main/java/org/dspace/app/rest/Application.java | 1 - 1 file changed, 1 deletion(-) diff --git a/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java b/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java index 41db8dda7d..0315860178 100644 --- a/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java +++ b/dspace-spring-rest/src/main/java/org/dspace/app/rest/Application.java @@ -22,7 +22,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.velocity.VelocityAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; From 705cc80a91207dac967eb0ffef9874871dd84b7d Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Tue, 9 Jul 2019 18:05:28 +0200 Subject: [PATCH 35/39] 63419: Bitstream format registry feedback --- .../rest/BitstreamFormatRestRepositoryIT.java | 340 +++++++++++++----- .../rest/builder/BitstreamFormatBuilder.java | 28 ++ .../rest/matcher/BitstreamFormatMatcher.java | 30 +- 3 files changed, 305 insertions(+), 93 deletions(-) diff --git a/dspace-spring-rest/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java b/dspace-spring-rest/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java index b76444b4cd..74b33df93c 100644 --- a/dspace-spring-rest/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java +++ b/dspace-spring-rest/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java @@ -7,6 +7,7 @@ */ package org.dspace.app.rest; +import static com.jayway.jsonpath.JsonPath.read; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.startsWith; @@ -21,6 +22,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import java.util.Arrays; import java.util.Map; import java.util.Random; +import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.dspace.app.rest.builder.BitstreamFormatBuilder; @@ -48,29 +50,32 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati @Autowired BitstreamFormatConverter converter; + private final int DEFAULT_AMOUNT_FORMATS = 80; + @Test public void findAllPaginationTest() throws Exception { getClient().perform(get("/api/core/bitstreamformats")) - .andExpect(status().isOk()) - .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$._links.self.href", startsWith(REST_SERVER_URL))) - .andExpect(jsonPath("$._links.self.href", endsWith("/api/core/bitstreamformats"))); + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.size", is(20))) + .andExpect(jsonPath("$._links.self.href", startsWith(REST_SERVER_URL))) + .andExpect(jsonPath("$._links.self.href", endsWith("/api/core/bitstreamformats"))) + ; } @Test @Ignore public void unknownFormatRequiredByDefault() throws Exception { getClient().perform(get("/api/core/bitstreamformats")) - .andExpect(status().isOk()) - .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andExpect(jsonPath("$._links.self.href", startsWith(REST_SERVER_URL))) - .andExpect(jsonPath("$._links.self.href", endsWith("/api/core/bitstreamformats"))) - .andExpect(jsonPath("$._embedded.bitstreamformats", Matchers.is( - BitstreamFormatMatcher.matchBitstreamFormatMimeType("Unknown") - ))); + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.size", is(20))) + .andExpect(jsonPath("$.page.totalElements", is(1))) + .andExpect(jsonPath("$._links.self.href", startsWith(REST_SERVER_URL))) + .andExpect(jsonPath("$._links.self.href", endsWith("/api/core/bitstreamformats"))) + .andExpect(jsonPath("$._embedded.bitstreamformats", Matchers.is( + BitstreamFormatMatcher.matchBitstreamFormatMimeType("Unknown") + ))); } @Test @@ -78,38 +83,38 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati public void findAllMimeTypeCheck() throws Exception { context.turnOffAuthorisationSystem(); BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) - .withMimeType("application/octet-stream") - .withDescription("Description") - .build(); + .withMimeType("application/octet-stream") + .withDescription("Description") + .build(); getClient().perform(get("/api/core/bitstreamformats")) - .andExpect(status().isOk()) - .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$.page.totalElements", is(2))) - .andExpect(jsonPath("$._embedded.bitstreamformats", Matchers.contains( - BitstreamFormatMatcher - .matchBitstreamFormat(bitstreamFormat.getMIMEType(), bitstreamFormat.getDescription()) - ))); + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.totalElements", is(2))) + .andExpect(jsonPath("$._embedded.bitstreamformats", Matchers.contains( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat.getMIMEType(), bitstreamFormat.getDescription()) + ))) + ; + } @Test public void findOne() throws Exception { context.turnOffAuthorisationSystem(); BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) - .withMimeType("application/octet-stream") - .withDescription("Description") - .build(); + .withMimeType("application/octet-stream") + .withDescription("Description") + .build(); context.restoreAuthSystemState(); getClient().perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) - .andExpect(status().isOk()) - .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$.description", is(bitstreamFormat.getDescription()))) - .andExpect(jsonPath("$.shortDescription", is(bitstreamFormat.getShortDescription()))) - .andExpect(jsonPath("$.mimetype", is(bitstreamFormat.getMIMEType()))) - .andExpect(jsonPath("$.type", is("bitstreamformat"))) - .andExpect(jsonPath("$._links.self.href", startsWith(REST_SERVER_URL))) - .andExpect(jsonPath("$._links.self.href", - endsWith("/api/core/bitstreamformats/" + bitstreamFormat.getID()))); + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat.getID(), bitstreamFormat.getMIMEType(), + bitstreamFormat.getDescription()) + ))); } @Test @@ -126,25 +131,44 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati BitstreamFormatRest bitstreamFormatRest = this.createRandomMockBitstreamRest(false); //Create bitstream format String token = getAuthToken(admin.getEmail(), password); - MvcResult mvcResult = getClient(token).perform(post("/api/core/bitstreamformats/") - .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) - .andExpect(status().isCreated()) - .andReturn(); - String content = mvcResult.getResponse().getContentAsString(); - Map map = mapper.readValue(content, Map.class); - String newlyCreatedBitstreamID = String.valueOf(map.get("id")); - //Verify creation - getClient().perform(get("/api/core/bitstreamformats/" + newlyCreatedBitstreamID)) - .andExpect(status().isOk()) - .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$.description", is(bitstreamFormatRest.getDescription()))) - .andExpect(jsonPath("$.shortDescription", is(bitstreamFormatRest.getShortDescription()))) - .andExpect(jsonPath("$.mimetype", is(bitstreamFormatRest.getMimetype()))) - .andExpect(jsonPath("$.type", is("bitstreamformat"))) - .andExpect(jsonPath("$._links.self.href", startsWith(REST_SERVER_URL))) - .andExpect(jsonPath("$._links.self.href", - endsWith("/api/core/bitstreamformats/" + newlyCreatedBitstreamID))); + // Capture the Id of the created BitstreamFormat (see andDo() below) + AtomicReference idRef = new AtomicReference<>(); + try { + + MvcResult mvcResult = getClient(token).perform(post("/api/core/bitstreamformats/") + .content(mapper.writeValueAsBytes( + bitstreamFormatRest)) + .contentType(contentType)) + .andExpect(status().isCreated()) + .andReturn(); + + String content = mvcResult.getResponse().getContentAsString(); + + + + Map map = mapper.readValue(content, Map.class); + String newlyCreatedBitstreamID = String.valueOf(map.get("id")); + //Verify creation + getClient().perform(get("/api/core/bitstreamformats/" + newlyCreatedBitstreamID)) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(Integer.parseInt(newlyCreatedBitstreamID), + bitstreamFormatRest.getMimetype(), + bitstreamFormatRest.getDescription(), + bitstreamFormatRest.getShortDescription()) + ))) + .andDo(result -> idRef + .set(read(result.getResponse().getContentAsString(), "$.id"))); + + } finally { + // Delete the created community (cleanup after ourselves!) + BitstreamFormatBuilder.deleteBitstreamFormat(idRef.get()); + } + + } @Test @@ -157,6 +181,11 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati getClient(token).perform(post("/api/core/bitstreamformats/") .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) .andExpect(status().isBadRequest()); + + // Check that no new bitstreamformat was created + getClient().perform(get("/api/core/bitstreamformats/")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.page.totalElements", is(DEFAULT_AMOUNT_FORMATS))); } @Test @@ -168,6 +197,11 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati getClient(null).perform(post("/api/core/bitstreamformats/") .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) .andExpect(status().isUnauthorized()); + + // Check that no new bitstreamformat was created + getClient().perform(get("/api/core/bitstreamformats/")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.page.totalElements", is(DEFAULT_AMOUNT_FORMATS))); } @Test @@ -187,21 +221,47 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati getClient(token).perform(post("/api/core/bitstreamformats/") .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) .andExpect(status().isForbidden()); + + // Check that no new bitstreamformat was created + getClient().perform(get("/api/core/bitstreamformats/")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.page.totalElements", is(DEFAULT_AMOUNT_FORMATS))); } @Test public void createAlreadyExisting() throws Exception { ObjectMapper mapper = new ObjectMapper(); BitstreamFormatRest bitstreamFormatRest = this.createRandomMockBitstreamRest(true); - //Try to create same bitstream twice - String token = getAuthToken(admin.getEmail(), password); - getClient(token).perform(post("/api/core/bitstreamformats/") - .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) - .andExpect(status().isCreated()); - //Second time it fails - getClient(token).perform(post("/api/core/bitstreamformats/") - .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) - .andExpect(status().isInternalServerError()); + + // Capture the Id of the created BitstreamFormat (see andDo() below) + AtomicReference idRef = new AtomicReference<>(); + try { + + + //Try to create same bitstream twice + String token = getAuthToken(admin.getEmail(), password); + getClient(token).perform(post("/api/core/bitstreamformats/") + .content(mapper.writeValueAsBytes(bitstreamFormatRest)) + .contentType(contentType)) + .andExpect(status().isCreated()) + .andDo(result -> idRef + .set(read(result.getResponse().getContentAsString(), "$.id"))); + //Second time it fails + getClient(token).perform(post("/api/core/bitstreamformats/") + .content(mapper.writeValueAsBytes(bitstreamFormatRest)) + .contentType(contentType)) + .andExpect(status().isInternalServerError()); + + // Check that the new bitstreamformat was created only once + getClient().perform(get("/api/core/bitstreamformats/")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.page.totalElements", is(DEFAULT_AMOUNT_FORMATS + 1))); + + + } finally { + // Delete the created community (cleanup after ourselves!) + BitstreamFormatBuilder.deleteBitstreamFormat(idRef.get()); + } } @Test @@ -225,15 +285,14 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati //Verify change getClient().perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) - .andExpect(status().isOk()) - .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$.description", is(bitstreamFormatRest.getDescription()))) - .andExpect(jsonPath("$.shortDescription", is(bitstreamFormatRest.getShortDescription()))) - .andExpect(jsonPath("$.mimetype", is(bitstreamFormatRest.getMimetype()))) - .andExpect(jsonPath("$.type", is("bitstreamformat"))) - .andExpect(jsonPath("$._links.self.href", startsWith(REST_SERVER_URL))) - .andExpect(jsonPath("$._links.self.href", - endsWith("/api/core/bitstreamformats/" + bitstreamFormat.getID()))); + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat.getID(), bitstreamFormatRest.getMimetype(), + bitstreamFormatRest.getDescription(), + bitstreamFormatRest.getShortDescription()) + ))); } @Test @@ -255,6 +314,17 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati getClient(token).perform(put("/api/core/bitstreamformats/" + bitstreamFormat.getID()) .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) .andExpect(status().isBadRequest()); + + getClient(token).perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat.getID(), + bitstreamFormat.getMIMEType(), + bitstreamFormat.getDescription(), + bitstreamFormat.getShortDescription()) + ))); } @Test @@ -263,9 +333,11 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati //Create bitstream format context.turnOffAuthorisationSystem(); BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) - .withMimeType("application/octet-stream") - .withDescription("Description - updateNonExistingIDInURLAndJSON") - .build(); + .withShortDescription("Test short") + .withMimeType("application/octet-stream") + .withDescription( + "Description - updateNonExistingIDInURLAndJSON") + .build(); context.restoreAuthSystemState(); int nonExistentBitstreamFormatID = 404404404; @@ -276,8 +348,20 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati bitstreamFormatRest.setShortDescription("Test short UPDATED"); bitstreamFormatRest.setId(nonExistentBitstreamFormatID); getClient(token).perform(put("/api/core/bitstreamformats/" + nonExistentBitstreamFormatID) - .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) - .andExpect(status().isNotFound()); + .content(mapper.writeValueAsBytes(bitstreamFormatRest)) + .contentType(contentType)) + .andExpect(status().isNotFound()); + + getClient(token).perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat.getID(), + bitstreamFormat.getMIMEType(), + bitstreamFormat.getDescription(), + bitstreamFormat.getShortDescription()) + ))); } @Test @@ -286,9 +370,11 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati //Create bitstream format context.turnOffAuthorisationSystem(); BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) - .withMimeType("application/octet-stream") - .withDescription("Description - updateNonExistingIDInJustURL") - .build(); + .withShortDescription("Test short") + .withMimeType("application/octet-stream") + .withDescription( + "Description - updateNonExistingIDInJustURL") + .build(); context.restoreAuthSystemState(); int nonExistentBitstreamFormatID = 404404404; @@ -298,8 +384,20 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati //Update it with non existent ID in URL bitstreamFormatRest.setShortDescription("Test short UPDATED"); getClient(token).perform(put("/api/core/bitstreamformats/" + nonExistentBitstreamFormatID) - .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) - .andExpect(status().isNotFound()); + .content(mapper.writeValueAsBytes(bitstreamFormatRest)) + .contentType(contentType)) + .andExpect(status().isNotFound()); + + getClient(token).perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat.getID(), + bitstreamFormat.getMIMEType(), + bitstreamFormat.getDescription(), + bitstreamFormat.getShortDescription()) + ))); } @Test @@ -307,7 +405,9 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati ObjectMapper mapper = new ObjectMapper(); //Create bitstream format context.turnOffAuthorisationSystem(); - BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) + BitstreamFormat bitstreamFormat = BitstreamFormatBuilder + .createBitstreamFormat(context) + .withShortDescription("Test short") .withMimeType("application/octet-stream") .withDescription("Description - updateNonExistingIDInJSONButValidInURL") .build(); @@ -321,8 +421,20 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati bitstreamFormatRest.setShortDescription("Test short UPDATED"); bitstreamFormatRest.setId(nonExistentBitstreamFormatID); getClient(token).perform(put("/api/core/bitstreamformats/" + bitstreamFormat.getID()) - .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) - .andExpect(status().isBadRequest()); + .content(mapper.writeValueAsBytes(bitstreamFormatRest)) + .contentType(contentType)) + .andExpect(status().isBadRequest()); + + getClient(token).perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat.getID(), + bitstreamFormat.getMIMEType(), + bitstreamFormat.getDescription(), + bitstreamFormat.getShortDescription()) + ))); } @Test @@ -331,6 +443,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati //Create bitstream format context.turnOffAuthorisationSystem(); BitstreamFormat bitstreamFormat1 = BitstreamFormatBuilder.createBitstreamFormat(context) + .withShortDescription("Test short") .withMimeType("application/octet-stream") .withDescription("Description - updateNotMatchingIDsInJSONAndURL 1") .build(); @@ -348,6 +461,17 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati getClient(token).perform(put("/api/core/bitstreamformats/" + bitstreamFormat1.getID()) .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) .andExpect(status().isBadRequest()); + + getClient().perform(get("/api/core/bitstreamformats/" + bitstreamFormat1.getID())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat1.getID(), bitstreamFormat1.getMIMEType(), + bitstreamFormat1.getDescription(), + bitstreamFormat1.getShortDescription()) + ))); + } @Test @@ -356,9 +480,10 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati //Create bitstream format context.turnOffAuthorisationSystem(); BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) - .withMimeType("application/octet-stream") - .withDescription("Description - updateNoAccess") - .build(); + .withShortDescription("Test short") + .withMimeType("application/octet-stream") + .withDescription("Description - updateNoAccess") + .build(); context.restoreAuthSystemState(); BitstreamFormatRest bitstreamFormatRest = converter.fromModel(bitstreamFormat); @@ -368,6 +493,16 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati getClient(null).perform(put("/api/core/bitstreamformats/" + bitstreamFormat.getID()) .content(mapper.writeValueAsBytes(bitstreamFormatRest)).contentType(contentType)) .andExpect(status().isUnauthorized()); + + getClient().perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat.getID(), bitstreamFormat.getMIMEType(), + bitstreamFormat.getDescription(), + bitstreamFormat.getShortDescription()) + ))); } @Test @@ -443,14 +578,25 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati //Create bitstream format context.turnOffAuthorisationSystem(); BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) - .withMimeType("application/octet-stream") - .withDescription("Description - updateAdminAccess") - .build(); + .withMimeType("application/octet-stream") + .withDescription("Description - updateAdminAccess") + .build(); context.restoreAuthSystemState(); //Delete it getClient(null).perform(delete("/api/core/bitstreamformats/" + bitstreamFormat.getID())) - .andExpect(status().isUnauthorized()); + .andExpect(status().isUnauthorized()); + + getClient().perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat.getID(), bitstreamFormat.getMIMEType(), + bitstreamFormat.getDescription(), + bitstreamFormat.getShortDescription()) + ))); + } @Test @@ -474,6 +620,16 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati String token = getAuthToken(user.getEmail(), password); getClient(token).perform(delete("/api/core/bitstreamformats/" + bitstreamFormat.getID())) .andExpect(status().isForbidden()); + + getClient().perform(get("/api/core/bitstreamformats/" + bitstreamFormat.getID())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", Matchers.is( + BitstreamFormatMatcher + .matchBitstreamFormat(bitstreamFormat.getID(), bitstreamFormat.getMIMEType(), + bitstreamFormat.getDescription(), + bitstreamFormat.getShortDescription()) + ))); } private BitstreamFormatRest createRandomMockBitstreamRest(boolean withRand) { diff --git a/dspace-spring-rest/src/test/java/org/dspace/app/rest/builder/BitstreamFormatBuilder.java b/dspace-spring-rest/src/test/java/org/dspace/app/rest/builder/BitstreamFormatBuilder.java index 5635386ae2..d098d8f145 100644 --- a/dspace-spring-rest/src/test/java/org/dspace/app/rest/builder/BitstreamFormatBuilder.java +++ b/dspace-spring-rest/src/test/java/org/dspace/app/rest/builder/BitstreamFormatBuilder.java @@ -7,6 +7,7 @@ */ package org.dspace.app.rest.builder; +import java.io.IOException; import java.sql.SQLException; import org.apache.logging.log4j.Logger; @@ -84,4 +85,31 @@ public class BitstreamFormatBuilder extends AbstractCRUDBuilder return this; } + public BitstreamFormatBuilder withShortDescription(String description) throws SQLException { + bitstreamFormat.setShortDescription(context, description); + return this; + } + + /** + * Delete the Test BitstreamFormat referred to by the given UUID + * @param id Id of Test BitstreamFormat to delete + * @throws SQLException + * @throws IOException + */ + public static void deleteBitstreamFormat(int id) throws SQLException, IOException { + try (Context c = new Context()) { + c.turnOffAuthorisationSystem(); + BitstreamFormat bitstreamFormat = bitstreamFormatService.find(c, id); + if (bitstreamFormat != null) { + try { + bitstreamFormatService.delete(c, bitstreamFormat); + } catch (AuthorizeException e) { + // cannot occur, just wrap it to make the compiler happy + throw new RuntimeException(e.getMessage(), e); + } + } + c.complete(); + } + } + } diff --git a/dspace-spring-rest/src/test/java/org/dspace/app/rest/matcher/BitstreamFormatMatcher.java b/dspace-spring-rest/src/test/java/org/dspace/app/rest/matcher/BitstreamFormatMatcher.java index ec5dc9f368..e9671535ac 100644 --- a/dspace-spring-rest/src/test/java/org/dspace/app/rest/matcher/BitstreamFormatMatcher.java +++ b/dspace-spring-rest/src/test/java/org/dspace/app/rest/matcher/BitstreamFormatMatcher.java @@ -8,8 +8,11 @@ package org.dspace.app.rest.matcher; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; +import static org.dspace.app.rest.test.AbstractControllerIntegrationTest.REST_SERVER_URL; import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.startsWith; import org.hamcrest.Matcher; @@ -18,7 +21,32 @@ import org.hamcrest.Matcher; */ public class BitstreamFormatMatcher { - private BitstreamFormatMatcher() { } + private BitstreamFormatMatcher() { + } + + public static Matcher matchBitstreamFormat(int id, String mimetype, String description) { + return allOf( + hasJsonPath("$.id", is(id)), + hasJsonPath("$.mimetype", is(mimetype)), + hasJsonPath("$.description", is(description)), + hasJsonPath("$.type", is("bitstreamformat")), + hasJsonPath("$._links.self.href", startsWith(REST_SERVER_URL)), + hasJsonPath("$._links.self.href", endsWith("/api/core/bitstreamformats/" + id)) + ); + } + + public static Matcher matchBitstreamFormat(int id, String mimetype, String description, + String shortDescription) { + return allOf( + hasJsonPath("$.id", is(id)), + hasJsonPath("$.description", is(description)), + hasJsonPath("$.shortDescription", is(shortDescription)), + hasJsonPath("$.mimetype", is(mimetype)), + hasJsonPath("$.type", is("bitstreamformat")), + hasJsonPath("$._links.self.href", startsWith(REST_SERVER_URL)), + hasJsonPath("$._links.self.href", endsWith("/api/core/bitstreamformats/" + id)) + ); + } public static Matcher matchBitstreamFormat(String mimetype, String description) { return allOf( From 5297c8829232bb094a0c0b505bd6eaf1ad1950da Mon Sep 17 00:00:00 2001 From: Kevin Van de Velde Date: Wed, 17 Jul 2019 11:36:37 +0200 Subject: [PATCH 36/39] Test that supportLevel is not changed --- .../app/rest/BitstreamFormatRestRepositoryIT.java | 11 +++++++++-- .../app/rest/builder/BitstreamFormatBuilder.java | 7 ++++++- .../app/rest/matcher/BitstreamFormatMatcher.java | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/dspace-spring-rest/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java b/dspace-spring-rest/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java index 74b33df93c..fa6ecaedfe 100644 --- a/dspace-spring-rest/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java +++ b/dspace-spring-rest/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java @@ -32,6 +32,7 @@ import org.dspace.app.rest.matcher.BitstreamFormatMatcher; import org.dspace.app.rest.model.BitstreamFormatRest; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.content.BitstreamFormat; +import org.dspace.content.service.BitstreamFormatService; import org.dspace.core.I18nUtil; import org.dspace.eperson.EPerson; import org.hamcrest.Matchers; @@ -50,6 +51,9 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati @Autowired BitstreamFormatConverter converter; + @Autowired + BitstreamFormatService bitstreamFormatService; + private final int DEFAULT_AMOUNT_FORMATS = 80; @Test @@ -303,6 +307,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati BitstreamFormat bitstreamFormat = BitstreamFormatBuilder.createBitstreamFormat(context) .withMimeType("application/octet-stream") .withDescription("Description - updateAdminAccess") + .withSupportLevel(BitstreamFormat.SUPPORTED) .build(); context.restoreAuthSystemState(); @@ -323,7 +328,9 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati .matchBitstreamFormat(bitstreamFormat.getID(), bitstreamFormat.getMIMEType(), bitstreamFormat.getDescription(), - bitstreamFormat.getShortDescription()) + bitstreamFormat.getShortDescription(), + bitstreamFormatService + .getSupportLevelText(bitstreamFormat)) ))); } @@ -647,4 +654,4 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati bitstreamFormatRest.setExtensions(Arrays.asList("txt", "asc")); return bitstreamFormatRest; } -} +} \ No newline at end of file diff --git a/dspace-spring-rest/src/test/java/org/dspace/app/rest/builder/BitstreamFormatBuilder.java b/dspace-spring-rest/src/test/java/org/dspace/app/rest/builder/BitstreamFormatBuilder.java index d098d8f145..266f4b153d 100644 --- a/dspace-spring-rest/src/test/java/org/dspace/app/rest/builder/BitstreamFormatBuilder.java +++ b/dspace-spring-rest/src/test/java/org/dspace/app/rest/builder/BitstreamFormatBuilder.java @@ -90,6 +90,11 @@ public class BitstreamFormatBuilder extends AbstractCRUDBuilder return this; } + public BitstreamFormatBuilder withSupportLevel(int supportLevel) throws SQLException { + bitstreamFormat.setSupportLevel(supportLevel); + return this; + } + /** * Delete the Test BitstreamFormat referred to by the given UUID * @param id Id of Test BitstreamFormat to delete @@ -112,4 +117,4 @@ public class BitstreamFormatBuilder extends AbstractCRUDBuilder } } -} +} \ No newline at end of file diff --git a/dspace-spring-rest/src/test/java/org/dspace/app/rest/matcher/BitstreamFormatMatcher.java b/dspace-spring-rest/src/test/java/org/dspace/app/rest/matcher/BitstreamFormatMatcher.java index e9671535ac..057c80598f 100644 --- a/dspace-spring-rest/src/test/java/org/dspace/app/rest/matcher/BitstreamFormatMatcher.java +++ b/dspace-spring-rest/src/test/java/org/dspace/app/rest/matcher/BitstreamFormatMatcher.java @@ -47,6 +47,19 @@ public class BitstreamFormatMatcher { hasJsonPath("$._links.self.href", endsWith("/api/core/bitstreamformats/" + id)) ); } + public static Matcher matchBitstreamFormat(int id, String mimetype, String description, + String shortDescription, String supportLevel) { + return allOf( + hasJsonPath("$.id", is(id)), + hasJsonPath("$.description", is(description)), + hasJsonPath("$.shortDescription", is(shortDescription)), + hasJsonPath("$.mimetype", is(mimetype)), + hasJsonPath("$.supportLevel", is(supportLevel)), + hasJsonPath("$.type", is("bitstreamformat")), + hasJsonPath("$._links.self.href", startsWith(REST_SERVER_URL)), + hasJsonPath("$._links.self.href", endsWith("/api/core/bitstreamformats/" + id)) + ); + } public static Matcher matchBitstreamFormat(String mimetype, String description) { return allOf( @@ -63,4 +76,4 @@ public class BitstreamFormatMatcher { ); } -} +} \ No newline at end of file From 86b90dc4900b444ccbab0e7d163f185ebb599d2c Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Thu, 18 Jul 2019 16:11:36 -0400 Subject: [PATCH 37/39] [DS-3872] From review: fix quoting in template, handle 0 arguments. --- .../src/main/java/org/dspace/core/Email.java | 24 +++++++++++-------- dspace/config/emails/register | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/core/Email.java b/dspace-api/src/main/java/org/dspace/core/Email.java index 15ff675805..5e7bbe2332 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -41,6 +41,7 @@ import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.internet.ParseException; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.velocity.Template; @@ -320,16 +321,16 @@ public class Email { vctx.put("params", Collections.unmodifiableList(arguments)); if (null == template) { - // No template, so look for a String of content. + if (StringUtils.isBlank(content)) { + // No template and no content -- PANIC!!! + throw new MessagingException("Email has no body"); + } + // No template, so use a String of content. StringResourceRepository repo = (StringResourceRepository) templateEngine.getApplicationAttribute(RESOURCE_REPOSITORY_NAME); repo.putStringResource(contentName, content); - if (null == content) { // SNH -- see constructor - // No template and no content -- PANIC!!! - throw new MessagingException("Email has no body"); - } else { // Turn content into a template. - template = templateEngine.getTemplate(contentName); - } + // Turn content into a template. + template = templateEngine.getTemplate(contentName); } StringWriter writer = new StringWriter(); @@ -433,7 +434,7 @@ public class Email { } /** - * Get the plain-text template for an email message. The message is suitable + * Get the VTL template for an email message. The message is suitable * for inserting values using Apache Velocity. * * @param emailFile @@ -485,7 +486,10 @@ public class Email { /** * Test method to send an email to check email server settings * - * @param args the command line arguments given + * @param args command line arguments. The first is the path to an email + * template file; the rest are the positional arguments for the + * template. If there are no arguments, a short, plain test + * message is sent. */ public static void main(String[] args) { ConfigurationService config @@ -498,7 +502,7 @@ public class Email { try { if (args.length <= 0) { message = new Email(); - message.content = "This is a test email sent from DSpace: " + url; + message.setContent("testing", "This is a test email sent from DSpace: " + url); } else { message = Email.getEmail(args[0]); for (int i = 1; i < args.length; i++) { diff --git a/dspace/config/emails/register b/dspace/config/emails/register index 15917195f2..1e60899d45 100644 --- a/dspace/config/emails/register +++ b/dspace/config/emails/register @@ -4,7 +4,7 @@ ## ## See org.dspace.core.Email for information on the format of this file. ## -#set($subject = "${config.get("dspace.name")} Account Registration") +#set($subject = "${config.get('dspace.name')} Account Registration") To complete registration for a DSpace account, please click the link below: From 739ff181cca010866c3307dea1a50aa9d128ca5a Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 28 Jun 2019 16:25:36 -0500 Subject: [PATCH 38/39] Rename "dspace-spring-rest" to "dspace-server-webapp" --- Dockerfile.jdk8 | 8 +- Dockerfile.jdk8-test | 8 +- README.md | 4 +- dspace-rest/pom.xml | 5 +- .../README.md | 8 +- .../pom.xml | 6 +- .../java/org/dspace/app/rest/Application.java | 0 .../rest/AuthenticationRestController.java | 0 .../rest/BitstreamContentRestController.java | 2 +- .../rest/DiscoverableEndpointsService.java | 0 .../app/rest/DiscoveryRestController.java | 0 .../app/rest/IdentifierRestController.java | 0 ...mOwningCollectionUpdateRestController.java | 0 .../dspace/app/rest/OpenSearchController.java | 0 .../java/org/dspace/app/rest/Parameter.java | 0 .../app/rest/RelationshipRestController.java | 0 .../rest/RelationshipTypeRestController.java | 0 .../app/rest/RestResourceController.java | 28 ++-- .../app/rest/RootRestResourceController.java | 0 .../org/dspace/app/rest/SearchRestMethod.java | 0 .../app/rest/UUIDLookupRestController.java | 0 .../rest/configuration/RESTSpringLoader.java | 0 .../converter/AInprogressItemConverter.java | 0 .../AuthorityEntryRestConverter.java | 0 .../converter/AuthorityRestConverter.java | 0 .../rest/converter/BitstreamConverter.java | 0 .../converter/BitstreamFormatConverter.java | 0 .../rest/converter/BrowseEntryConverter.java | 0 .../rest/converter/BrowseIndexConverter.java | 0 .../rest/converter/ClaimedTaskConverter.java | 0 .../rest/converter/CollectionConverter.java | 0 .../rest/converter/CommunityConverter.java | 0 .../app/rest/converter/DSpaceConverter.java | 0 .../rest/converter/DSpaceObjectConverter.java | 0 .../DiscoverConfigurationConverter.java | 0 .../DiscoverFacetConfigurationConverter.java | 0 .../DiscoverFacetResultsConverter.java | 0 .../DiscoverFacetValueConverter.java | 0 .../converter/DiscoverFacetsConverter.java | 0 .../converter/DiscoverResultConverter.java | 0 .../DiscoverSearchSupportConverter.java | 0 .../app/rest/converter/EPersonConverter.java | 0 .../rest/converter/EntityTypeConverter.java | 0 .../FilteredDiscoveryPageConverter.java | 0 .../GenericDSpaceObjectConverter.java | 0 .../app/rest/converter/GroupConverter.java | 0 .../converter/IndexableObjectConverter.java | 0 .../app/rest/converter/ItemConverter.java | 0 .../rest/converter/JsonPatchConverter.java | 0 .../app/rest/converter/MetadataConverter.java | 0 .../converter/MetadataFieldConverter.java | 0 .../converter/MetadataSchemaConverter.java | 0 .../converter/MetadataValueConverter.java | 0 .../app/rest/converter/PatchConverter.java | 0 .../app/rest/converter/PoolTaskConverter.java | 0 .../rest/converter/RelationshipConverter.java | 0 .../converter/RelationshipTypeConverter.java | 0 .../converter/ResourcePolicyConverter.java | 0 .../app/rest/converter/RootConverter.java | 0 .../SearchFilterToAppliedFilterConverter.java | 0 .../app/rest/converter/SiteConverter.java | 0 .../SubmissionDefinitionConverter.java | 0 .../converter/SubmissionFormConverter.java | 0 .../converter/SubmissionSectionConverter.java | 0 .../rest/converter/WorkflowItemConverter.java | 0 .../converter/WorkspaceItemConverter.java | 0 .../converter/query/SearchQueryConverter.java | 0 .../DSpaceApiExceptionControllerAdvice.java | 0 .../exception/DSpaceBadRequestException.java | 0 .../exception/MissingParameterException.java | 0 .../rest/exception/PaginationException.java | 0 .../exception/RESTAuthorizationException.java | 0 ...positoryMethodNotImplementedException.java | 0 .../RepositoryNotFoundException.java | 0 ...positorySearchMethodNotFoundException.java | 0 .../RepositorySearchNotFoundException.java | 0 .../UnprocessableEntityException.java | 0 .../filter/DSpaceRequestContextFilter.java | 0 .../app/rest/link/AuthnHalLinkFactory.java | 0 .../link/AuthorityEntryHalLinkFactory.java | 0 .../rest/link/BrowseEntryHalLinkFactory.java | 0 .../link/DSpaceResourceHalLinkFactory.java | 0 .../dspace/app/rest/link/HalLinkFactory.java | 0 .../dspace/app/rest/link/HalLinkService.java | 0 .../app/rest/link/RootHalLinkFactory.java | 0 .../link/SubmissionSectionHalLinkFactory.java | 0 .../relation/EntityTypeHalLinkFactory.java | 0 .../relation/RelationshipHalLinkFactory.java | 0 ...shipTypeResourceWrapperHalLinkFactory.java | 0 .../search/DiscoveryRestHalLinkFactory.java | 0 ...etConfigurationResourceHalLinkFactory.java | 0 .../search/FacetResultsHalLinkFactory.java | 0 .../search/FacetsResourceHalLinkFactory.java | 0 ...chConfigurationResourceHalLinkFactory.java | 0 .../SearchFacetEntryHalLinkFactory.java | 0 .../SearchFacetValueHalLinkFactory.java | 0 .../SearchResultEntryHalLinkFactory.java | 0 .../SearchResultsResourceHalLinkFactory.java | 0 .../search/SearchSupportHalLinkFactory.java | 0 .../rest/model/AInprogressSubmissionRest.java | 0 .../rest/model/AccessConditionOptionRest.java | 0 .../rest/model/AuthenticationStatusRest.java | 0 .../org/dspace/app/rest/model/AuthnRest.java | 0 .../app/rest/model/AuthorityEntryRest.java | 0 .../dspace/app/rest/model/AuthorityRest.java | 0 .../dspace/app/rest/model/BaseObjectRest.java | 0 .../app/rest/model/BitstreamFormatRest.java | 0 .../dspace/app/rest/model/BitstreamRest.java | 0 .../app/rest/model/BrowseEntryRest.java | 0 .../app/rest/model/BrowseIndexRest.java | 0 .../dspace/app/rest/model/CheckSumRest.java | 0 .../app/rest/model/ClaimedTaskRest.java | 0 .../dspace/app/rest/model/CollectionRest.java | 0 .../dspace/app/rest/model/CommunityRest.java | 0 .../app/rest/model/DSpaceObjectRest.java | 0 .../app/rest/model/DiscoveryResultsRest.java | 0 .../dspace/app/rest/model/EPersonRest.java | 0 .../dspace/app/rest/model/EntityTypeRest.java | 0 .../org/dspace/app/rest/model/ErrorRest.java | 0 .../rest/model/FacetConfigurationRest.java | 0 .../app/rest/model/FacetResultsRest.java | 0 .../rest/model/FilteredDiscoveryPageRest.java | 0 .../org/dspace/app/rest/model/GroupRest.java | 0 .../org/dspace/app/rest/model/ItemRest.java | 0 .../dspace/app/rest/model/LicenseRest.java | 0 .../org/dspace/app/rest/model/LinkRest.java | 0 .../org/dspace/app/rest/model/LinksRest.java | 0 .../app/rest/model/MetadataFieldRest.java | 0 .../dspace/app/rest/model/MetadataRest.java | 0 .../app/rest/model/MetadataSchemaRest.java | 0 .../app/rest/model/MetadataValueRest.java | 0 .../dspace/app/rest/model/PoolTaskRest.java | 0 .../app/rest/model/RelationshipRest.java | 0 .../app/rest/model/RelationshipTypeRest.java | 0 .../model/RelationshipTypeRestWrapper.java | 0 .../app/rest/model/ResourcePolicyRest.java | 0 .../app/rest/model/RestAddressableModel.java | 0 .../org/dspace/app/rest/model/RestModel.java | 0 .../org/dspace/app/rest/model/RootRest.java | 0 .../org/dspace/app/rest/model/ScopeEnum.java | 0 .../rest/model/SearchConfigurationRest.java | 0 .../app/rest/model/SearchFacetEntryRest.java | 0 .../app/rest/model/SearchFacetValueRest.java | 0 .../app/rest/model/SearchResultEntryRest.java | 0 .../app/rest/model/SearchResultsRest.java | 0 .../app/rest/model/SearchSupportRest.java | 0 .../org/dspace/app/rest/model/SiteRest.java | 0 .../rest/model/SubmissionDefinitionRest.java | 0 .../rest/model/SubmissionFormFieldRest.java | 0 .../model/SubmissionFormInputTypeRest.java | 0 .../app/rest/model/SubmissionFormRest.java | 0 .../app/rest/model/SubmissionFormRowRest.java | 0 .../app/rest/model/SubmissionSectionRest.java | 0 .../app/rest/model/SubmissionUploadRest.java | 0 .../rest/model/SubmissionVisibilityRest.java | 0 .../dspace/app/rest/model/VisibilityEnum.java | 0 .../app/rest/model/WorkflowItemRest.java | 0 .../app/rest/model/WorkspaceItemRest.java | 0 .../hateoas/AuthenticationStatusResource.java | 0 .../app/rest/model/hateoas/AuthnResource.java | 0 .../model/hateoas/AuthorityEntryResource.java | 0 .../rest/model/hateoas/AuthorityResource.java | 0 .../hateoas/BitstreamFormatResource.java | 0 .../rest/model/hateoas/BitstreamResource.java | 0 .../model/hateoas/BrowseEntryResource.java | 0 .../model/hateoas/BrowseIndexResource.java | 0 .../model/hateoas/ClaimedTaskResource.java | 0 .../model/hateoas/CollectionResource.java | 0 .../rest/model/hateoas/CommunityResource.java | 0 .../rest/model/hateoas/DSpaceRelProvider.java | 0 .../rest/model/hateoas/DSpaceResource.java | 0 .../rest/model/hateoas/EPersonResource.java | 0 .../app/rest/model/hateoas/EmbeddedPage.java | 0 .../model/hateoas/EmbeddedPageHeader.java | 0 .../model/hateoas/EntityTypeResource.java | 0 .../hateoas/FacetConfigurationResource.java | 0 .../model/hateoas/FacetResultsResource.java | 0 .../rest/model/hateoas/FacetsResource.java | 0 .../FilteredDiscoveryPageResource.java | 0 .../app/rest/model/hateoas/GroupResource.java | 0 .../app/rest/model/hateoas/HALResource.java | 0 .../app/rest/model/hateoas/ItemResource.java | 0 .../rest/model/hateoas/LicenseResource.java | 0 .../model/hateoas/MetadataFieldResource.java | 0 .../model/hateoas/MetadataSchemaResource.java | 0 .../rest/model/hateoas/PoolTaskResource.java | 0 .../model/hateoas/RelationshipResource.java | 0 .../hateoas/RelationshipTypeResource.java | 0 .../RelationshipTypeResourceWrapper.java | 0 .../model/hateoas/ResourcePolicyResource.java | 0 .../app/rest/model/hateoas/RootResource.java | 0 .../hateoas/SearchConfigurationResource.java | 0 .../hateoas/SearchFacetEntryResource.java | 0 .../hateoas/SearchFacetValueResource.java | 0 .../hateoas/SearchResultEntryResource.java | 0 .../model/hateoas/SearchResultsResource.java | 0 .../model/hateoas/SearchSupportResource.java | 0 .../app/rest/model/hateoas/SiteResource.java | 0 .../hateoas/SubmissionDefinitionResource.java | 0 .../model/hateoas/SubmissionFormResource.java | 0 .../hateoas/SubmissionSectionResource.java | 0 .../hateoas/SubmissionUploadResource.java | 0 .../model/hateoas/WorkflowItemResource.java | 0 .../model/hateoas/WorkspaceItemResource.java | 0 .../annotations/RelNameDSpaceResource.java | 0 .../app/rest/model/patch/AddOperation.java | 0 .../app/rest/model/patch/CopyOperation.java | 0 .../app/rest/model/patch/FromOperation.java | 0 .../rest/model/patch/JsonValueEvaluator.java | 0 .../rest/model/patch/LateObjectEvaluator.java | 0 .../app/rest/model/patch/MoveOperation.java | 0 .../app/rest/model/patch/Operation.java | 0 .../dspace/app/rest/model/patch/Patch.java | 0 .../app/rest/model/patch/RemoveOperation.java | 0 .../rest/model/patch/ReplaceOperation.java | 0 .../rest/model/query/RestSearchOperator.java | 0 .../app/rest/model/step/DataDescribe.java | 0 .../app/rest/model/step/DataLicense.java | 0 .../app/rest/model/step/DataUpload.java | 0 .../app/rest/model/step/SectionData.java | 0 .../rest/model/step/UploadBitstreamRest.java | 0 .../rest/model/step/UploadStatusResponse.java | 0 .../app/rest/parameter/SearchFilter.java | 0 .../resolver/SearchFilterResolver.java | 0 .../AbstractDSpaceRestRepository.java | 0 .../AuthorityEntryLinkRepository.java | 0 .../AuthorityEntryValueLinkRepository.java | 0 .../repository/AuthorityRestRepository.java | 0 .../BitstreamFormatRestRepository.java | 0 .../repository/BitstreamRestRepository.java | 0 .../repository/BrowseEntryLinkRepository.java | 0 .../repository/BrowseIndexRestRepository.java | 0 .../repository/BrowseItemLinkRepository.java | 0 .../repository/ClaimedTaskRestRepository.java | 0 .../repository/CollectionRestRepository.java | 0 .../repository/CommunityRestRepository.java | 0 .../DSpaceObjectRestRepository.java | 0 .../rest/repository/DSpaceRestRepository.java | 0 .../repository/DiscoveryRestRepository.java | 0 .../repository/EPersonRestRepository.java | 0 .../repository/EntityTypeRestRepository.java | 0 .../FilteredDiscoveryPageRestRepository.java | 0 .../rest/repository/GroupRestRepository.java | 0 .../rest/repository/ItemRestRepository.java | 0 .../repository/LicenseRestLinkRepository.java | 0 .../rest/repository/LinkRestRepository.java | 0 .../MetadataFieldRestRepository.java | 0 .../MetadataSchemaRestRepository.java | 0 .../repository/PoolTaskRestRepository.java | 0 .../RelationshipRestRepository.java | 0 .../RelationshipTypeRestRepository.java | 0 .../ResourcePolicyRestRepository.java | 0 .../rest/repository/RootRestRepository.java | 0 .../rest/repository/SiteRestRepository.java | 0 .../SubmissionDefinitionRestRepository.java | 0 .../SubmissionFormRestRepository.java | 0 .../SubmissionPanelRestRepository.java | 0 .../SubmissionUploadRestRepository.java | 0 .../WorkflowItemRestRepository.java | 0 .../WorkspaceItemRestRepository.java | 0 .../patch/AbstractResourcePatch.java | 0 .../repository/patch/DSpaceObjectPatch.java | 0 .../rest/repository/patch/EPersonPatch.java | 0 .../app/rest/repository/patch/ItemPatch.java | 0 .../factories/EPersonOperationFactory.java | 0 .../patch/factories/ItemOperationFactory.java | 0 .../EPersonCertificateReplaceOperation.java | 0 .../impl/EPersonEmailReplaceOperation.java | 0 .../impl/EPersonLoginReplaceOperation.java | 0 .../impl/EPersonNetidReplaceOperation.java | 0 .../impl/EPersonPasswordReplaceOperation.java | 0 .../ItemDiscoverableReplaceOperation.java | 0 .../impl/ItemWithdrawReplaceOperation.java | 0 .../patch/factories/impl/PatchOperation.java | 0 .../factories/impl/ReplacePatchOperation.java | 0 .../impl/ResourcePatchOperation.java | 0 .../AdminRestPermissionEvaluatorPlugin.java | 0 ...orizeServicePermissionEvaluatorPlugin.java | 0 ...imedTaskRestPermissionEvaluatorPlugin.java | 0 .../rest/security/CustomLogoutHandler.java | 0 .../DSpace401AuthenticationEntryPoint.java | 0 .../rest/security/DSpaceAuthentication.java | 0 .../security/DSpacePermissionEvaluator.java | 0 .../rest/security/DSpaceRestPermission.java | 0 .../EPersonRestAuthenticationProvider.java | 0 .../EPersonRestPermissionEvaluatorPlugin.java | 0 .../GroupRestPermissionEvaluatorPlugin.java | 0 .../rest/security/MethodSecurityConfig.java | 0 ...PoolTaskRestPermissionEvaluatorPlugin.java | 0 .../security/RestAuthenticationService.java | 0 .../RestObjectPermissionEvaluatorPlugin.java | 0 .../RestPermissionEvaluatorPlugin.java | 0 .../StatelessAuthenticationFilter.java | 0 .../rest/security/StatelessLoginFilter.java | 0 .../security/WebSecurityConfiguration.java | 0 ...WorkflowRestPermissionEvaluatorPlugin.java | 0 .../security/jwt/EPersonClaimProvider.java | 0 .../rest/security/jwt/JWTClaimProvider.java | 0 .../rest/security/jwt/JWTTokenHandler.java | 0 ...JWTTokenRestAuthenticationServiceImpl.java | 0 .../jwt/SpecialGroupClaimProvider.java | 0 .../submit/AbstractRestProcessingStep.java | 0 .../rest/submit/ListenerProcessingStep.java | 0 .../submit/PatchConfigurationService.java | 0 .../app/rest/submit/SubmissionService.java | 0 .../app/rest/submit/UploadableStep.java | 0 .../submit/factory/PatchOperationFactory.java | 0 .../factory/impl/AddPatchOperation.java | 0 ...tstreamMetadataValueAddPatchOperation.java | 0 ...streamMetadataValueMovePatchOperation.java | 0 ...reamMetadataValueRemovePatchOperation.java | 0 ...eamMetadataValueReplacePatchOperation.java | 0 .../impl/BitstreamMovePatchOperation.java | 0 .../impl/BitstreamRemovePatchOperation.java | 0 .../impl/CollectionReplacePatchOperation.java | 0 .../ItemMetadataValueAddPatchOperation.java | 0 .../ItemMetadataValueMovePatchOperation.java | 0 ...ItemMetadataValueRemovePatchOperation.java | 0 ...temMetadataValueReplacePatchOperation.java | 0 .../impl/LicenseAddPatchOperation.java | 2 +- .../impl/LicenseRemovePatchOperation.java | 2 +- .../impl/LicenseReplacePatchOperation.java | 0 .../impl/MetadataValueAddPatchOperation.java | 0 .../impl/MetadataValueMovePatchOperation.java | 0 .../MetadataValueRemovePatchOperation.java | 0 .../MetadataValueReplacePatchOperation.java | 0 .../factory/impl/MovePatchOperation.java | 0 .../submit/factory/impl/PatchOperation.java | 0 .../factory/impl/RemovePatchOperation.java | 0 .../factory/impl/ReplacePatchOperation.java | 0 .../impl/ResourcePolicyAddPatchOperation.java | 0 .../ResourcePolicyRemovePatchOperation.java | 0 .../ResourcePolicyReplacePatchOperation.java | 0 .../app/rest/submit/step/CollectionStep.java | 0 .../app/rest/submit/step/DescribeStep.java | 0 .../rest/submit/step/ExtractMetadataStep.java | 0 .../app/rest/submit/step/LicenseStep.java | 0 .../app/rest/submit/step/UploadStep.java | 0 .../step/validation/AbstractValidation.java | 0 .../step/validation/LicenseValidation.java | 0 .../step/validation/MetadataValidation.java | 0 .../step/validation/UploadValidation.java | 0 .../submit/step/validation/Validation.java | 0 .../app/rest/utils/ApplicationConfig.java | 0 .../dspace/app/rest/utils/AuthorityUtils.java | 0 .../utils/CollectionRestEqualityUtils.java | 0 .../utils/CommunityRestEqualityUtils.java | 0 .../dspace/app/rest/utils/ContextUtil.java | 0 .../utils/DSpaceConfigurationInitializer.java | 0 .../rest/utils/DSpaceKernelInitializer.java | 0 .../utils/DSpaceObjectRestEqualityUtils.java | 0 .../dspace/app/rest/utils/DateMathParser.java | 0 .../app/rest/utils/DiscoverQueryBuilder.java | 0 .../app/rest/utils/MultipartFileSender.java | 0 .../app/rest/utils/RestRepositoryUtils.java | 0 .../dspace/app/rest/utils/ScopeResolver.java | 0 .../org/dspace/app/rest/utils/URLUtils.java | 0 .../java/org/dspace/app/rest/utils/Utils.java | 0 .../src/main/resources/application.properties | 0 .../main/resources/i18n/messages.properties | 0 ...pring-dspace-addon-validation-services.xml | 0 .../spring/spring-dspace-core-services.xml | 0 .../src/main/webapp/index.html | 0 .../src/main/webapp/js/hal/http/client.js | 0 .../src/main/webapp/login.html | 0 .../java/org/dspace/app/oai/OAIpmhIT.java | 0 .../OpenSearchControllerDisabledIT.java | 0 .../opensearch/OpenSearchControllerIT.java | 0 .../test/java/org/dspace/app/rdf/RdfIT.java | 0 .../rest/AuthenticationRestControllerIT.java | 0 .../BitstreamContentRestControllerIT.java | 0 .../rest/BitstreamFormatRestRepositoryIT.java | 0 .../app/rest/BitstreamRestRepositoryIT.java | 0 .../app/rest/BrowsesResourceControllerIT.java | 0 .../app/rest/CollectionRestRepositoryIT.java | 0 .../app/rest/CommunityRestRepositoryIT.java | 0 .../app/rest/DiscoveryRestControllerIT.java | 0 .../app/rest/EPersonRestRepositoryIT.java | 0 .../app/rest/EmptyRestRepositoryIT.java | 0 .../app/rest/EntityTypeRestRepositoryIT.java | 0 .../app/rest/GroupRestRepositoryIT.java | 0 .../app/rest/IdentifierRestControllerIT.java | 0 .../dspace/app/rest/InitializeEntitiesIT.java | 0 ...wningCollectionUpdateRestControllerIT.java | 0 .../dspace/app/rest/ItemRestRepositoryIT.java | 0 .../rest/MetadataSchemaRestRepositoryIT.java | 0 .../rest/MetadatafieldRestRepositoryIT.java | 0 .../rest/RelationshipRestRepositoryIT.java | 132 +++++++++--------- .../RelationshipTypeRestControllerIT.java | 0 .../RelationshipTypeRestRepositoryIT.java | 0 .../app/rest/RestResourceControllerIT.java | 0 .../rest/RootRestResourceControllerIT.java | 0 .../dspace/app/rest/SiteRestRepositoryIT.java | 0 .../SubmissionDefinitionsControllerIT.java | 0 .../app/rest/SubmissionFormsControllerIT.java | 0 .../rest/SubmissionSectionsControllerIT.java | 0 .../rest/SubmissionUploadsControllerIT.java | 0 .../app/rest/TaskRestRepositoriesIT.java | 0 .../app/rest/UUIDLookupRestControllerIT.java | 0 .../org/dspace/app/rest/UriListParsingIT.java | 4 +- .../rest/WorkflowItemRestRepositoryIT.java | 0 .../rest/WorkspaceItemRestRepositoryIT.java | 0 .../app/rest/builder/AbstractBuilder.java | 0 .../app/rest/builder/AbstractCRUDBuilder.java | 0 .../builder/AbstractDSpaceObjectBuilder.java | 0 .../app/rest/builder/BitstreamBuilder.java | 0 .../rest/builder/BitstreamFormatBuilder.java | 0 .../app/rest/builder/ClaimedTaskBuilder.java | 0 .../app/rest/builder/CollectionBuilder.java | 0 .../app/rest/builder/CommunityBuilder.java | 0 .../app/rest/builder/EPersonBuilder.java | 0 .../app/rest/builder/EntityTypeBuilder.java | 0 .../dspace/app/rest/builder/GroupBuilder.java | 0 .../dspace/app/rest/builder/ItemBuilder.java | 0 .../rest/builder/MetadataFieldBuilder.java | 0 .../rest/builder/MetadataSchemaBuilder.java | 0 .../app/rest/builder/PoolTaskBuilder.java | 0 .../app/rest/builder/RelationshipBuilder.java | 0 .../rest/builder/RelationshipTypeBuilder.java | 0 .../rest/builder/ResourcePolicyBuilder.java | 0 .../dspace/app/rest/builder/SiteBuilder.java | 0 .../app/rest/builder/WorkflowItemBuilder.java | 0 .../rest/builder/WorkspaceItemBuilder.java | 0 .../util/AbstractBuilderCleanupUtil.java | 0 .../DiscoverConfigurationConverterTest.java | 0 ...scoverFacetConfigurationConverterTest.java | 0 .../DiscoverSearchSupportConverterTest.java | 0 .../app/rest/converter/RootConverterTest.java | 0 .../query/SearchQueryConverterTest.java | 0 .../org/dspace/app/rest/csv/CsvImportIT.java | 0 ...nfigurationResourceHalLinkFactoryTest.java | 0 ...nfigurationResourceHalLinkFactoryTest.java | 0 ...archResultsResourceHalLinkFactoryTest.java | 0 .../SearchSupportHalLinkFactoryTest.java | 0 .../rest/matcher/AppliedFilterMatcher.java | 0 .../rest/matcher/BitstreamFormatMatcher.java | 0 .../app/rest/matcher/BitstreamMatcher.java | 0 .../matcher/BrowseEntryResourceMatcher.java | 0 .../app/rest/matcher/BrowseIndexMatcher.java | 0 .../app/rest/matcher/ClaimedTaskMatcher.java | 0 .../app/rest/matcher/CollectionMatcher.java | 0 .../app/rest/matcher/CommunityMatcher.java | 0 .../app/rest/matcher/DSpaceObjectMatcher.java | 0 .../app/rest/matcher/EPersonMatcher.java | 0 .../app/rest/matcher/EntityTypeMatcher.java | 0 .../app/rest/matcher/FacetEntryMatcher.java | 0 .../app/rest/matcher/FacetValueMatcher.java | 0 .../dspace/app/rest/matcher/GroupMatcher.java | 0 .../app/rest/matcher/HitHighlightMatcher.java | 0 .../dspace/app/rest/matcher/ItemMatcher.java | 0 .../rest/matcher/MetadataFieldMatcher.java | 0 .../app/rest/matcher/MetadataMatcher.java | 0 .../rest/matcher/MetadataschemaMatcher.java | 0 .../dspace/app/rest/matcher/PageMatcher.java | 0 .../app/rest/matcher/PoolTaskMatcher.java | 0 .../app/rest/matcher/RelationshipMatcher.java | 0 .../rest/matcher/RelationshipTypeMatcher.java | 0 .../app/rest/matcher/SearchFilterMatcher.java | 0 .../app/rest/matcher/SearchResultMatcher.java | 0 .../dspace/app/rest/matcher/SiteMatcher.java | 0 .../app/rest/matcher/SortOptionMatcher.java | 0 .../matcher/SubmissionDefinitionsMatcher.java | 0 .../matcher/SubmissionFormFieldMatcher.java | 0 .../app/rest/matcher/WorkflowItemMatcher.java | 0 .../rest/matcher/WorkspaceItemMatcher.java | 0 .../model/FacetConfigurationRestTest.java | 0 .../app/rest/model/FacetResultsRestTest.java | 0 .../model/SearchConfigurationRestTest.java | 0 .../app/rest/model/SearchSupportRestTest.java | 0 .../FacetConfigurationResourceTest.java | 0 .../rest/model/hateoas/RootResourceTest.java | 0 .../SearchConfigurationResourceTest.java | 0 .../hateoas/SearchSupportResourceTest.java | 0 ...EPersonRestAuthenticationProviderTest.java | 0 ...rsonRestPermissionEvaluatorPluginTest.java | 0 .../jwt/EPersonClaimProviderTest.java | 0 .../security/jwt/JWTTokenHandlerTest.java | 0 .../jwt/SpecialGroupClaimProviderTest.java | 0 .../AbstractControllerIntegrationTest.java | 0 .../test/AbstractDSpaceIntegrationTest.java | 0 .../test/AbstractEntityIntegrationTest.java | 0 .../AbstractIntegrationTestWithDatabase.java | 0 .../AbstractWebClientIntegrationTest.java | 0 .../dspace/app/rest/test/ExitException.java | 0 .../app/rest/test/MetadataPatchSuite.java | 0 .../app/rest/test/NoExitSecurityManager.java | 0 .../rest/utils/DiscoverQueryBuilderTest.java | 0 .../rest/utils/MultipartFileSenderTest.java | 0 .../java/org/dspace/app/sword/Swordv1IT.java | 0 .../java/org/dspace/app/sword2/Swordv2IT.java | 0 .../org/dspace/core/HibernateTestUtil.java | 0 .../dspace/discovery/MockSolrServiceImpl.java | 0 .../dspace/identifier/MockDOIConnector.java | 0 .../java/org/dspace/solr/MockSolrServer.java | 0 .../dspace/statistics/FakeDatabaseReader.java | 0 .../statistics/MockSolrLoggerServiceImpl.java | 0 .../src/test/resources/log4j.properties | 0 .../src/test/resources/logback.xml | 0 .../org/dspace/app/rest/bibtex-test.bib | 0 .../org/dspace/app/rest/simple-article.pdf | Bin .../app/rest/test/metadata-patch-suite.json | 0 .../src/test/resources/test-config.properties | 0 dspace/config/dspace.cfg | 2 +- dspace/modules/pom.xml | 56 +------- dspace/modules/rest/pom.xml | 5 +- .../modules/{spring-rest => server}/pom.xml | 14 +- .../src/main/webapp/.gitignore | 0 dspace/pom.xml | 4 +- pom.xml | 10 +- 509 files changed, 129 insertions(+), 171 deletions(-) rename {dspace-spring-rest => dspace-server-webapp}/README.md (87%) rename {dspace-spring-rest => dspace-server-webapp}/pom.xml (99%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/Application.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/AuthenticationRestController.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/BitstreamContentRestController.java (98%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/DiscoverableEndpointsService.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/DiscoveryRestController.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/IdentifierRestController.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/OpenSearchController.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/Parameter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/RelationshipRestController.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/RelationshipTypeRestController.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/RestResourceController.java (98%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/RootRestResourceController.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/SearchRestMethod.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/configuration/RESTSpringLoader.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/AuthorityEntryRestConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/AuthorityRestConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/BitstreamConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/BitstreamFormatConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/BrowseEntryConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/BrowseIndexConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/CollectionConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/CommunityConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/DSpaceConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/DSpaceObjectConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/DiscoverConfigurationConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/DiscoverFacetConfigurationConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/DiscoverFacetResultsConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/DiscoverFacetValueConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/DiscoverFacetsConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/DiscoverResultConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/DiscoverSearchSupportConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/EPersonConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/EntityTypeConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/FilteredDiscoveryPageConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/GenericDSpaceObjectConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/GroupConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/IndexableObjectConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/ItemConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/JsonPatchConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/MetadataConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/MetadataFieldConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/MetadataSchemaConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/MetadataValueConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/PatchConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/RelationshipConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/RelationshipTypeConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/ResourcePolicyConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/RootConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/SearchFilterToAppliedFilterConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/SiteConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/SubmissionDefinitionConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/SubmissionFormConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/WorkflowItemConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/WorkspaceItemConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/converter/query/SearchQueryConverter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/exception/DSpaceBadRequestException.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/exception/MissingParameterException.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/exception/PaginationException.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/exception/RESTAuthorizationException.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/exception/RepositoryMethodNotImplementedException.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/exception/RepositoryNotFoundException.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/exception/RepositorySearchMethodNotFoundException.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/exception/RepositorySearchNotFoundException.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/exception/UnprocessableEntityException.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/filter/DSpaceRequestContextFilter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/AuthnHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/AuthorityEntryHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/BrowseEntryHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/DSpaceResourceHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/HalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/HalLinkService.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/RootHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/SubmissionSectionHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/relation/EntityTypeHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/relation/RelationshipHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/relation/RelationshipTypeResourceWrapperHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/search/DiscoveryRestHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/search/FacetConfigurationResourceHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/search/FacetResultsHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/search/FacetsResourceHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/search/SearchConfigurationResourceHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/search/SearchFacetEntryHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/search/SearchFacetValueHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/search/SearchResultEntryHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/search/SearchResultsResourceHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/link/search/SearchSupportHalLinkFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/AInprogressSubmissionRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/AccessConditionOptionRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/AuthenticationStatusRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/AuthnRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/AuthorityEntryRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/AuthorityRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/BaseObjectRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/BitstreamFormatRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/BitstreamRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/BrowseEntryRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/BrowseIndexRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/CheckSumRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/ClaimedTaskRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/CollectionRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/CommunityRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/DSpaceObjectRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/DiscoveryResultsRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/EPersonRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/EntityTypeRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/ErrorRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/FacetConfigurationRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/FacetResultsRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/FilteredDiscoveryPageRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/GroupRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/ItemRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/LicenseRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/LinkRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/LinksRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/MetadataFieldRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/MetadataRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/MetadataSchemaRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/MetadataValueRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/RelationshipRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/RelationshipTypeRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/RelationshipTypeRestWrapper.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/ResourcePolicyRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/RestAddressableModel.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/RestModel.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/RootRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/ScopeEnum.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SearchConfigurationRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SearchFacetEntryRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SearchFacetValueRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SearchResultEntryRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SearchResultsRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SearchSupportRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SiteRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SubmissionDefinitionRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SubmissionFormFieldRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SubmissionFormInputTypeRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SubmissionFormRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SubmissionFormRowRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SubmissionSectionRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SubmissionUploadRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/SubmissionVisibilityRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/VisibilityEnum.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/AuthenticationStatusResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/AuthnResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/AuthorityEntryResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/AuthorityResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/BitstreamFormatResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/BitstreamResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/BrowseEntryResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/BrowseIndexResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/ClaimedTaskResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/CollectionResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/CommunityResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/DSpaceRelProvider.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/DSpaceResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/EPersonResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/EmbeddedPage.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/EmbeddedPageHeader.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/EntityTypeResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/FacetConfigurationResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/FacetResultsResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/FacetsResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/FilteredDiscoveryPageResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/GroupResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/HALResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/ItemResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/LicenseResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/MetadataFieldResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/MetadataSchemaResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/PoolTaskResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipTypeResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/RelationshipTypeResourceWrapper.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/ResourcePolicyResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/RootResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SearchConfigurationResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SearchFacetEntryResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SearchFacetValueResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SearchResultEntryResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SearchResultsResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SearchSupportResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SiteResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionDefinitionResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionFormResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionSectionResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/SubmissionUploadResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/WorkflowItemResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/WorkspaceItemResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/hateoas/annotations/RelNameDSpaceResource.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/patch/AddOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/patch/CopyOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/patch/FromOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/patch/JsonValueEvaluator.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/patch/LateObjectEvaluator.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/patch/MoveOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/patch/Operation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/patch/Patch.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/patch/RemoveOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/patch/ReplaceOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/query/RestSearchOperator.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/step/DataDescribe.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/step/DataLicense.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/step/DataUpload.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/step/SectionData.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/step/UploadBitstreamRest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/model/step/UploadStatusResponse.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/parameter/SearchFilter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/parameter/resolver/SearchFilterResolver.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/AbstractDSpaceRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/AuthorityEntryLinkRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/AuthorityEntryValueLinkRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/AuthorityRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/BitstreamFormatRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/BitstreamRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/BrowseEntryLinkRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/BrowseIndexRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/BrowseItemLinkRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/CommunityRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/DSpaceObjectRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/DSpaceRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/DiscoveryRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/EPersonRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/FilteredDiscoveryPageRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/GroupRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/LicenseRestLinkRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/LinkRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/MetadataSchemaRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/RelationshipTypeRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/RootRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/SiteRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/SubmissionDefinitionRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/SubmissionFormRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/SubmissionPanelRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/WorkflowItemRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/WorkspaceItemRestRepository.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/AbstractResourcePatch.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/DSpaceObjectPatch.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/EPersonPatch.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/ItemPatch.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/EPersonOperationFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/ItemOperationFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonCertificateReplaceOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonEmailReplaceOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonLoginReplaceOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonNetidReplaceOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/EPersonPasswordReplaceOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ItemDiscoverableReplaceOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ItemWithdrawReplaceOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/PatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ReplacePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/repository/patch/factories/impl/ResourcePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/AdminRestPermissionEvaluatorPlugin.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/AuthorizeServicePermissionEvaluatorPlugin.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/ClaimedTaskRestPermissionEvaluatorPlugin.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/CustomLogoutHandler.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/DSpace401AuthenticationEntryPoint.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/DSpaceAuthentication.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/DSpacePermissionEvaluator.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/DSpaceRestPermission.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/EPersonRestAuthenticationProvider.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/EPersonRestPermissionEvaluatorPlugin.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/GroupRestPermissionEvaluatorPlugin.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/MethodSecurityConfig.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/PoolTaskRestPermissionEvaluatorPlugin.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/RestAuthenticationService.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/RestObjectPermissionEvaluatorPlugin.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/RestPermissionEvaluatorPlugin.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/StatelessAuthenticationFilter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/StatelessLoginFilter.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/WebSecurityConfiguration.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/WorkflowRestPermissionEvaluatorPlugin.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/jwt/EPersonClaimProvider.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/jwt/JWTClaimProvider.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/jwt/JWTTokenHandler.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/jwt/JWTTokenRestAuthenticationServiceImpl.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/security/jwt/SpecialGroupClaimProvider.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/AbstractRestProcessingStep.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/ListenerProcessingStep.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/PatchConfigurationService.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/SubmissionService.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/UploadableStep.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/PatchOperationFactory.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/AddPatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamMetadataValueAddPatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamMetadataValueMovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamMetadataValueRemovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamMetadataValueReplacePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamMovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamRemovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/CollectionReplacePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/ItemMetadataValueAddPatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/ItemMetadataValueMovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/ItemMetadataValueRemovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/ItemMetadataValueReplacePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseAddPatchOperation.java (96%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseRemovePatchOperation.java (92%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/LicenseReplacePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/MetadataValueAddPatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/MetadataValueMovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/MetadataValueRemovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/MetadataValueReplacePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/MovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/PatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/RemovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/ReplacePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/ResourcePolicyAddPatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/ResourcePolicyRemovePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/factory/impl/ResourcePolicyReplacePatchOperation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/step/CollectionStep.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/step/DescribeStep.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/step/ExtractMetadataStep.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/step/LicenseStep.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/step/UploadStep.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/step/validation/AbstractValidation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/step/validation/LicenseValidation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/step/validation/MetadataValidation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/step/validation/UploadValidation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/submit/step/validation/Validation.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/ApplicationConfig.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/AuthorityUtils.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/CollectionRestEqualityUtils.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/CommunityRestEqualityUtils.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/ContextUtil.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/DSpaceConfigurationInitializer.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/DSpaceKernelInitializer.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/DSpaceObjectRestEqualityUtils.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/DateMathParser.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/DiscoverQueryBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/MultipartFileSender.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/RestRepositoryUtils.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/ScopeResolver.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/URLUtils.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/java/org/dspace/app/rest/utils/Utils.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/resources/application.properties (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/resources/i18n/messages.properties (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/resources/spring/spring-dspace-addon-validation-services.xml (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/resources/spring/spring-dspace-core-services.xml (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/webapp/index.html (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/webapp/js/hal/http/client.js (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/main/webapp/login.html (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/oai/OAIpmhIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/opensearch/OpenSearchControllerDisabledIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/opensearch/OpenSearchControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rdf/RdfIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/AuthenticationRestControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/BitstreamContentRestControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/BitstreamFormatRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/BitstreamRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/EmptyRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/EntityTypeRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/IdentifierRestControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/InitializeEntitiesIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/MetadatafieldRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java (96%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/RelationshipTypeRestControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/RelationshipTypeRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/RestResourceControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/RootRestResourceControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/SiteRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/SubmissionFormsControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/SubmissionSectionsControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/SubmissionUploadsControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/UUIDLookupRestControllerIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/UriListParsingIT.java (95%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/AbstractBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/AbstractCRUDBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/AbstractDSpaceObjectBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/BitstreamBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/BitstreamFormatBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/ClaimedTaskBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/CollectionBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/CommunityBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/EPersonBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/EntityTypeBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/GroupBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/ItemBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/MetadataFieldBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/MetadataSchemaBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/PoolTaskBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/RelationshipBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/RelationshipTypeBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/ResourcePolicyBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/SiteBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/WorkflowItemBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/WorkspaceItemBuilder.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/builder/util/AbstractBuilderCleanupUtil.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/converter/DiscoverConfigurationConverterTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/converter/DiscoverFacetConfigurationConverterTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/converter/DiscoverSearchSupportConverterTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/converter/RootConverterTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/converter/query/SearchQueryConverterTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/csv/CsvImportIT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/link/search/FacetConfigurationResourceHalLinkFactoryTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/link/search/SearchConfigurationResourceHalLinkFactoryTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/link/search/SearchResultsResourceHalLinkFactoryTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/link/search/SearchSupportHalLinkFactoryTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/AppliedFilterMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/BitstreamFormatMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/BitstreamMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/BrowseIndexMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/ClaimedTaskMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/CollectionMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/CommunityMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/DSpaceObjectMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/EPersonMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/EntityTypeMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/FacetEntryMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/GroupMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/HitHighlightMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/ItemMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/MetadataFieldMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/MetadataMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/MetadataschemaMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/PageMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/PoolTaskMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/RelationshipMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/RelationshipTypeMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/SearchFilterMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/SearchResultMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/SiteMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/SortOptionMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/SubmissionDefinitionsMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/SubmissionFormFieldMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/WorkflowItemMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/matcher/WorkspaceItemMatcher.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/model/FacetConfigurationRestTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/model/FacetResultsRestTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/model/SearchConfigurationRestTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/model/SearchSupportRestTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/model/hateoas/FacetConfigurationResourceTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/model/hateoas/RootResourceTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/model/hateoas/SearchConfigurationResourceTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/model/hateoas/SearchSupportResourceTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/security/EPersonRestAuthenticationProviderTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/security/EPersonRestPermissionEvaluatorPluginTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/security/jwt/EPersonClaimProviderTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/security/jwt/JWTTokenHandlerTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/security/jwt/SpecialGroupClaimProviderTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/test/AbstractControllerIntegrationTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/test/AbstractDSpaceIntegrationTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/test/AbstractEntityIntegrationTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/test/AbstractIntegrationTestWithDatabase.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/test/AbstractWebClientIntegrationTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/test/ExitException.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/test/MetadataPatchSuite.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/test/NoExitSecurityManager.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/utils/DiscoverQueryBuilderTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/rest/utils/MultipartFileSenderTest.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/sword/Swordv1IT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/app/sword2/Swordv2IT.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/core/HibernateTestUtil.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/discovery/MockSolrServiceImpl.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/identifier/MockDOIConnector.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/solr/MockSolrServer.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/statistics/FakeDatabaseReader.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/java/org/dspace/statistics/MockSolrLoggerServiceImpl.java (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/resources/log4j.properties (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/resources/logback.xml (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/resources/org/dspace/app/rest/bibtex-test.bib (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/resources/org/dspace/app/rest/simple-article.pdf (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/resources/org/dspace/app/rest/test/metadata-patch-suite.json (100%) rename {dspace-spring-rest => dspace-server-webapp}/src/test/resources/test-config.properties (100%) rename dspace/modules/{spring-rest => server}/pom.xml (94%) rename dspace/modules/{spring-rest => server}/src/main/webapp/.gitignore (100%) diff --git a/Dockerfile.jdk8 b/Dockerfile.jdk8 index b5c108d129..c205fc846e 100644 --- a/Dockerfile.jdk8 +++ b/Dockerfile.jdk8 @@ -1,11 +1,11 @@ # This image will be published as dspace/dspace # See https://dspace-labs.github.io/DSpace-Docker-Images/ for usage details -# +# # This version is JDK8 compatible # - tomcat:8-jre8 # - ANT 1.10.5 # - maven:3-jdk-8 -# - note: +# - note: # - default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x-jdk8 # Step 1 - Run Maven Build @@ -55,6 +55,6 @@ EXPOSE 8080 8009 ENV JAVA_OPTS=-Xmx2000m RUN mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT.bk && \ - ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/ROOT && \ - ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/spring-rest && \ + ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/ROOT && \ + ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/server && \ ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest diff --git a/Dockerfile.jdk8-test b/Dockerfile.jdk8-test index 54ef4d105f..f528c5fb36 100644 --- a/Dockerfile.jdk8-test +++ b/Dockerfile.jdk8-test @@ -1,11 +1,11 @@ # This image will be published as dspace/dspace # See https://dspace-labs.github.io/DSpace-Docker-Images/ for usage details -# +# # This version is JDK8 compatible # - tomcat:8-jre8 # - ANT 1.10.5 # - maven:3-jdk-8 -# - note: +# - note: # - default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x-jdk8-test # Step 1 - Run Maven Build @@ -55,8 +55,8 @@ EXPOSE 8080 8009 ENV JAVA_OPTS=-Xmx2000m RUN mv /usr/local/tomcat/webapps/ROOT /usr/local/tomcat/webapps/ROOT.bk && \ - ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/ROOT && \ - ln -s $DSPACE_INSTALL/webapps/spring-rest /usr/local/tomcat/webapps/spring-rest && \ + ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/ROOT && \ + ln -s $DSPACE_INSTALL/webapps/server /usr/local/tomcat/webapps/server && \ ln -s $DSPACE_INSTALL/webapps/rest /usr/local/tomcat/webapps/rest COPY dspace/src/main/docker/test/rest_web.xml $DSPACE_INSTALL/webapps/rest/WEB-INF/web.xml diff --git a/README.md b/README.md index aac6b7e6cc..13b68d3f18 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ For more information, visit http://www.dspace.org/ *** :warning: **Work on DSpace 7 has begun on our `master` branch.** This means that there is temporarily NO user interface on this `master` branch. DSpace 7 will feature a new, unified [Angular](https://angular.io/) user interface, along with an enhanced, rebuilt REST API. The latest status of this work can be found on the [DSpace 7 UI Working Group](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Working+Group) page. Additionally, the codebases can be found in the following places: - * DSpace 7 REST API work is occurring on the [`master` branch](https://github.com/DSpace/DSpace/tree/master/dspace-spring-rest) of this repository. + * DSpace 7 REST API work is occurring on the [`master` branch](https://github.com/DSpace/DSpace/tree/master/dspace-server-webapp) of this repository. * The REST Contract is being documented at https://github.com/DSpace/Rest7Contract * DSpace 7 Angular UI work is occurring at https://github.com/DSpace/dspace-angular @@ -126,7 +126,7 @@ run automatically by [Travis CI](https://travis-ci.org/DSpace/DSpace/) for all P mvn clean install # Then, move into a module subdirectory, and run the test command - cd [dspace-src]/dspace-spring-rest + cd [dspace-src]/dspace-server-webapp # Choose your test command from the lists above ``` diff --git a/dspace-rest/pom.xml b/dspace-rest/pom.xml index 4e5f898032..3c06a15027 100644 --- a/dspace-rest/pom.xml +++ b/dspace-rest/pom.xml @@ -4,8 +4,9 @@ dspace-rest war 7.0-SNAPSHOT - DSpace REST :: API and Implementation - DSpace RESTful Web Services API + DSpace (Deprecated) REST Webapp + DSpace RESTful Web Services API. NOTE: this REST API is DEPRECATED. + Please consider using the REST API in the dspace-server-webapp instead! http://demo.dspace.org diff --git a/dspace-spring-rest/README.md b/dspace-server-webapp/README.md similarity index 87% rename from dspace-spring-rest/README.md rename to dspace-server-webapp/README.md index 2def91d522..e71039308a 100644 --- a/dspace-spring-rest/README.md +++ b/dspace-server-webapp/README.md @@ -1,5 +1,5 @@ -# DSpace7 REST Webapp -> This is the new REST webapp for DSpace 7 build with Spring MVC + HATEOAS with a focus on the [JSON HAL format](http://stateless.co/hal_specification.html) ([formal specification](https://tools.ietf.org/html/draft-kelly-json-hal-08)) +# DSpace Server Webapp +> This is the new server webapp for DSpace 7 built with Spring Boot, MVC + HATEOAS with a focus on the [JSON HAL format](http://stateless.co/hal_specification.html) ([formal specification](https://tools.ietf.org/html/draft-kelly-json-hal-08)) This webapp uses the following technologies: - [Spring Boot](https://projects.spring.io/spring-boot/) @@ -15,8 +15,8 @@ Check the infomation available on the DSpace Official Wiki page for the [DSpace [DSpace 7 REST: Coding DSpace Objects](https://wiki.duraspace.org/display/DSPACE/DSpace+7+REST%3A+Coding+DSpace+Objects) ## How to run -The only tested way right now is to run this webapp inside your IDE (Eclipse). Just create a new Tomcat 8 server and deploy the dspace-spring-rest maven module to it. -> The *dspace.dir* is configured in the *dspace-spring-rest/src/main/resources/application.properties* file +The only tested way right now is to run this webapp inside your IDE (Eclipse). Just create a new Tomcat 8 server and deploy the dspace-server-webapp maven module to it. +> The *dspace.dir* is configured in the *dspace-server-webapp/src/main/resources/application.properties* file [currently](src/main/resources/application.properties#L25) > dspace.dir = d:/install/dspace7 diff --git a/dspace-spring-rest/pom.xml b/dspace-server-webapp/pom.xml similarity index 99% rename from dspace-spring-rest/pom.xml rename to dspace-server-webapp/pom.xml index 6b6fbb7911..0c872184ff 100644 --- a/dspace-spring-rest/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -1,11 +1,11 @@ 4.0.0 org.dspace - dspace-spring-rest + dspace-server-webapp war - DSpace Spring Rest (Boot MVC + HATEOAS) + DSpace Server Webapp - DSpace new Rest API + DSpace Server Webapp (Spring Boot) - - dspace-rdf - - - rdf/pom.xml - - - - rdf - - dspace-rest @@ -62,47 +51,14 @@ - dspace-sword + dspace-server-webapp` - sword/pom.xml + server/pom.xml - sword - - - - dspace-swordv2 - - - swordv2/pom.xml - - - - swordv2 - - - - dspace-oai - - - oai/pom.xml - - - - oai - - - - dspace-spring-rest - - - spring-rest/pom.xml - - - - spring-rest + server diff --git a/dspace/modules/rest/pom.xml b/dspace/modules/rest/pom.xml index 4b9c4a2a24..e6962b5da3 100644 --- a/dspace/modules/rest/pom.xml +++ b/dspace/modules/rest/pom.xml @@ -3,10 +3,11 @@ org.dspace.modules rest war - DSpace REST :: Local Customizations + DSpace (Deprecated) REST Webapp :: Local Customizations This project allows you to overlay your own local REST customizations - on top of the default REST API provided with DSpace. + on top of the deprecated REST API provided with DSpace. NOTE: This REST API is DEPRECATED. Please consider + using the REST API in dspace-server-webapp instead. diff --git a/dspace/modules/spring-rest/pom.xml b/dspace/modules/server/pom.xml similarity index 94% rename from dspace/modules/spring-rest/pom.xml rename to dspace/modules/server/pom.xml index b8d834a3f8..710867affd 100644 --- a/dspace/modules/spring-rest/pom.xml +++ b/dspace/modules/server/pom.xml @@ -1,13 +1,13 @@ 4.0.0 org.dspace.modules - spring-rest + server war - DSpace Spring Rest:: Local Customizations - Overlay REST customizations. -This is probably a temporary solution to the build problems. We like to investigate about -the possibility to remove the overlays enable a more flexible extension mechanism. -The use of web-fragment and spring mvc technology allow us to add request handlers + DSpace Server Webapp:: Local Customizations + Overlay customizations. +This is probably a temporary solution to the build problems. We like to investigate about +the possibility to remove the overlays enable a more flexible extension mechanism. +The use of web-fragment and spring mvc technology allow us to add request handlers just adding new jar in the classloader @@ -101,7 +101,7 @@ just adding new jar in the classloader org.dspace - dspace-spring-rest + dspace-server-webapp war diff --git a/dspace/modules/spring-rest/src/main/webapp/.gitignore b/dspace/modules/server/src/main/webapp/.gitignore similarity index 100% rename from dspace/modules/spring-rest/src/main/webapp/.gitignore rename to dspace/modules/server/src/main/webapp/.gitignore diff --git a/dspace/pom.xml b/dspace/pom.xml index bf46f313bf..c03dab19db 100644 --- a/dspace/pom.xml +++ b/dspace/pom.xml @@ -218,7 +218,7 @@ org.dspace - dspace-spring-rest + dspace-server-webapp war compile @@ -267,7 +267,7 @@ ${project.parent.basedir}/dspace-rdf/src/main/java ${project.parent.basedir}/dspace-rest/src/main/java ${project.parent.basedir}/dspace-services/src/main/java - ${project.parent.basedir}/dspace-spring-rest/src/main/java + ${project.parent.basedir}/dspace-server-webapp/src/main/java ${project.parent.basedir}/dspace-sword/src/main/java ${project.parent.basedir}/dspace-swordv2/src/main/java diff --git a/pom.xml b/pom.xml index 86d53c29f0..a7fbb0d05a 100644 --- a/pom.xml +++ b/pom.xml @@ -822,14 +822,14 @@ - dspace-spring-rest + dspace-server-webapp - dspace-spring-rest/pom.xml + dspace-server-webapp/pom.xml - dspace-spring-rest + dspace-server-webapp @@ -854,7 +854,7 @@ dspace-services dspace-sword dspace-swordv2 - dspace-spring-rest + dspace-server-webapp @@ -980,7 +980,7 @@ org.dspace - dspace-spring-rest + dspace-server-webapp 7.0-SNAPSHOT war From 8dc1d275987cf3a991fc8c9966d4f72bc804d103 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 19 Jul 2019 12:44:41 -0500 Subject: [PATCH 39/39] Correct sample URLs in tests --- .../org/dspace/app/rest/RelationshipRestRepositoryIT.java | 4 ++-- .../src/test/java/org/dspace/app/rest/UriListParsingIT.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java index f4c1856ce9..eb0b2544e1 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java @@ -239,8 +239,8 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest (org.springframework.data.rest.webmvc.RestMediaTypes .TEXT_URI_LIST_VALUE)) .content( - "https://localhost:8080/api/core/items/" + publication.getID() + "\n" + - "https://localhost:8080/api/core/items/" + author1.getID())) + "https://localhost:8080/server/api/core/items/" + publication.getID() + "\n" + + "https://localhost:8080/server/api/core/items/" + author1.getID())) .andExpect(status().isCreated()) .andReturn(); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/UriListParsingIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/UriListParsingIT.java index 890932e57f..108859381e 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/UriListParsingIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/UriListParsingIT.java @@ -71,8 +71,8 @@ public class UriListParsingIT extends AbstractControllerIntegrationTest { MockHttpServletRequest mockRequest = new MockHttpServletRequest(); - String uriListString = "https://localhost:8080/api/core/items/" + publicItem1.getID() + "\n" + - "https://localhost:8080/api/core/items/" + publicItem2.getID(); + String uriListString = "https://localhost:8080/server/api/core/items/" + publicItem1.getID() + "\n" + + "https://localhost:8080/server/api/core/items/" + publicItem2.getID(); mockRequest.setContentType("text/uri-list"); mockRequest.setContent(uriListString.getBytes()); List dSpaceObjectList = utils.constructDSpaceObjectList(