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-jdk15onorg.bouncycastle
- bcmail-jdk15
+ bcmail-jdk15onorg.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.dspacehandle
- 6.2
+ 9.1.0org.dspace
@@ -1289,13 +1289,13 @@
org.bouncycastle
- bcprov-jdk15
- 1.46
+ bcprov-jdk15on
+ 1.59org.bouncycastle
- bcmail-jdk15
- 1.46
+ bcmail-jdk15on
+ 1.59org.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.dspacehandle
+
+ org.eclipse.jetty.aggregate
+ jetty-all
+
+
+ javax.servlet
+ org.eclipse.jetty.orbit
+
+
+ org.dspacejargon
diff --git a/pom.xml b/pom.xml
index 0e3e3060cf..59ec40c6aa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1128,6 +1128,17 @@
handle9.1.0
+
+ org.eclipse.jetty.aggregate
+ jetty-all
+ 8.1.22.v20160922
+
+
+ javax.servlet
+ org.eclipse.jetty.orbit
+
+
+ org.dspacejargon
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.dspacehandle
- 9.1.0
+ 9.1.0.v20190416org.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 @@
json20180130
+
+ 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
+
org.apache.velocity
- velocity
- 1.7
+ velocity-engine-core
+ 2.0jar
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]}".
*
*
- * 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-lang33.7
+
+ org.apache.commons
+ commons-lang3
+ 3.5
+ commons-loggingcommons-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-lang33.7