From c4159cff0d31e4fb99d73914f6dd382abb6716e5 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Tue, 27 Jun 2023 17:01:32 -0400 Subject: [PATCH 01/37] More and better(?) documentation. --- .../src/main/java/org/dspace/core/Email.java | 116 +++++++++++++----- 1 file changed, 84 insertions(+), 32 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 998d934c9558..a95407876e11 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -57,26 +57,40 @@ import org.dspace.services.factory.DSpaceServicesFactory; /** - * Class representing an e-mail message, also used to send e-mails. + * Class representing an e-mail message. The {@link send} method causes the + * assembled message to be formatted and sent. *

* Typical use: - *

+ *
+ * Email email = Email.getEmail(path);
+ * email.addRecipient("foo@bar.com");
+ * email.addArgument("John");
+ * email.addArgument("On the Testing of DSpace");
+ * email.send();
+ * 
+ * {@code path} is the filesystem path of an email template, typically in + * {@code ${dspace.dir}/config/emails/} and can include the subject -- see + * below. Templates are processed by + * Apache Velocity. They may contain VTL directives and property + * placeholders. + *

+ * {@link addArgument(string)} adds a property to the {@code params} array + * in the Velocity context, which can be used to replace placeholder tokens + * in the message. These arguments are indexed by number in the order they were + * added to the message. *

- * Email email = new Email();
- * email.addRecipient("foo@bar.com");
- * email.addArgument("John");
- * email.addArgument("On the Testing of DSpace");
- * email.send();
- *

+ * The DSpace configuration properties are also available to templates as the + * array {@code config}, indexed by name. Example: {@code ${config.get('dspace.name')}} *

- * name is the name of an email template in - * dspace-dir/config/emails/ (which also includes the subject.) - * arg0 and arg1 are arguments to fill out the - * message with. - *

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

+ * Recipients and attachments may be added as needed. See {@link addRecipient}, + * {@link addAttachment(File, String)}, and + * {@link addAttachment(InputStream, String, String)}. + *

+ * Headers such as Subject may be supplied by the template, by defining them + * using the VTL directive {@code #set()}. Only headers named in the DSpace + * configuration array property {@code mail.message.headers} will be added. + *

+ * Example: * *

  *
@@ -91,12 +105,14 @@
  *
  *     Thank you for sending us your submission "${params[1]}".
  *
+ *     --
+ *     The ${config.get('dspace.name')} Team
+ *
  * 
* *

* If the example code above was used to send this mail, the resulting mail * would have the subject Example e-mail and the body would be: - *

* *
  *
@@ -105,7 +121,16 @@
  *
  *     Thank you for sending us your submission "On the Testing of DSpace".
  *
+ *     --
+ *     The DSpace Team
+ *
  * 
+ *

+ * There are two ways to load a message body. One can create an instance of + * {@link Email} and call {@link setContent} on it, passing the body as a String. Or + * one can use the static factory method {@link getEmail} to load a file by its + * complete filesystem path. In either case the text will be loaded into a + * Velocity template. * * @author Robert Tansley * @author Jim Downing - added attachment handling code @@ -182,7 +207,7 @@ public Email() { } /** - * Add a recipient + * Add a recipient. * * @param email the recipient's email address */ @@ -205,7 +230,7 @@ public void setContent(String name, String cnt) { } /** - * Set the subject of the message + * Set the subject of the message. * * @param s the subject of the message */ @@ -214,7 +239,7 @@ public void setSubject(String s) { } /** - * Set the reply-to email address + * Set the reply-to email address. * * @param email the reply-to email address */ @@ -223,7 +248,7 @@ public void setReplyTo(String email) { } /** - * Fill out the next argument in the template + * Fill out the next argument in the template. * * @param arg the value for the next argument */ @@ -231,6 +256,13 @@ public void addArgument(Object arg) { arguments.add(arg); } + /** + * Add an attachment bodypart to the message from an external file. + * + * @param f reference to a file to be attached. + * @param name a name for the resulting bodypart in the message's MIME + * structure. + */ public void addAttachment(File f, String name) { attachments.add(new FileAttachment(f, name)); } @@ -238,6 +270,17 @@ public void addAttachment(File f, String name) { /** When given a bad MIME type for an attachment, use this instead. */ private static final String DEFAULT_ATTACHMENT_TYPE = "application/octet-stream"; + /** + * Add an attachment bodypart to the message from a byte stream. + * + * @param is the content of this stream will become the content of the + * bodypart. + * @param name a name for the resulting bodypart in the message's MIME + * structure. + * @param mimetype the MIME type of the resulting bodypart, such as + * "text/pdf". If {@code null} it will default to + * "application/octet-stream", which is MIME for "unknown format". + */ public void addAttachment(InputStream is, String name, String mimetype) { if (null == mimetype) { LOG.error("Null MIME type replaced with '" + DEFAULT_ATTACHMENT_TYPE @@ -257,6 +300,11 @@ public void addAttachment(InputStream is, String name, String mimetype) { moreAttachments.add(new InputStreamAttachment(is, name, mimetype)); } + /** + * Set the character set of the message. + * + * @param cs the name of a character set, such as "UTF-8" or "EUC-JP". + */ public void setCharset(String cs) { charset = cs; } @@ -447,6 +495,9 @@ public void send() throws MessagingException, IOException { /** * Get the VTL template for an email message. The message is suitable * for inserting values using Apache Velocity. + *

+ * Note that everything is stored here, so that only send() throws a + * MessagingException. * * @param emailFile * full name for the email template, for example "/dspace/config/emails/register". @@ -484,15 +535,6 @@ public static Email getEmail(String emailFile) } return email; } - /* - * Implementation note: It might be necessary to add a quick utility method - * like "send(to, subject, message)". We'll see how far we get without it - - * having all emails as templates in the config allows customisation and - * internationalisation. - * - * Note that everything is stored and the run in send() so that only send() - * throws a MessagingException. - */ /** * Test method to send an email to check email server settings @@ -547,7 +589,7 @@ public static void main(String[] args) { } /** - * Utility struct class for handling file attachments. + * Utility record class for handling file attachments. * * @author ojd20 */ @@ -563,7 +605,7 @@ public FileAttachment(File f, String n) { } /** - * Utility struct class for handling file attachments. + * Utility record class for handling file attachments. * * @author Adán Román Ruiz at arvo.es */ @@ -580,6 +622,8 @@ public InputStreamAttachment(InputStream is, String name, String mimetype) { } /** + * Wrap an {@link InputStream} in a {@link DataSource}. + * * @author arnaldo */ public static class InputStreamDataSource implements DataSource { @@ -587,6 +631,14 @@ public static class InputStreamDataSource implements DataSource { private final String contentType; private final ByteArrayOutputStream baos; + /** + * Consume the content of an InputStream and store it in a local buffer. + * + * @param name give the DataSource a name. + * @param contentType the DataSource contains this type of data. + * @param inputStream content to be buffered in the DataSource. + * @throws IOException if the stream cannot be read. + */ InputStreamDataSource(String name, String contentType, InputStream inputStream) throws IOException { this.name = name; this.contentType = contentType; From a30454ca5a523c532e353a63270bb5a32fbd3e70 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Tue, 27 Jun 2023 17:05:21 -0400 Subject: [PATCH 02/37] Don't clear the list of accepted embedded message header properties. Why was this cleared? --- dspace-api/src/main/java/org/dspace/core/Email.java | 3 +-- 1 file changed, 1 insertion(+), 2 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 a95407876e11..a64a85a07351 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -378,13 +378,12 @@ public void send() throws MessagingException, IOException { // No template and no content -- PANIC!!! throw new MessagingException("Email has no body"); } - // No template, so use a String of content. + // No existing template, so use a String of content. StringResourceRepository repo = (StringResourceRepository) templateEngine.getApplicationAttribute(RESOURCE_REPOSITORY_NAME); repo.putStringResource(contentName, content); // Turn content into a template. template = templateEngine.getTemplate(contentName); - templateHeaders = new String[] {}; } StringWriter writer = new StringWriter(); From d939786a46ed7bc141ea240a86c8a509161ca4b5 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Tue, 27 Jun 2023 17:23:26 -0400 Subject: [PATCH 03/37] Simplify and modernize the code. Store content directly in the template. --- .../src/main/java/org/dspace/core/Email.java | 58 ++++++++----------- 1 file changed, 25 insertions(+), 33 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 a64a85a07351..f6df740a53ef 100644 --- a/dspace-api/src/main/java/org/dspace/core/Email.java +++ b/dspace-api/src/main/java/org/dspace/core/Email.java @@ -21,7 +21,6 @@ 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; @@ -41,7 +40,6 @@ import javax.mail.internet.MimeMultipart; import javax.mail.internet.ParseException; -import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.velocity.Template; @@ -140,7 +138,6 @@ public class Email { /** * The content of the message */ - private String content; private String contentName; /** @@ -201,7 +198,6 @@ public Email() { moreAttachments = new ArrayList<>(10); subject = ""; template = null; - content = ""; replyTo = null; charset = null; } @@ -221,12 +217,20 @@ public void addRecipient(String email) { * "Subject:" line must be stripped. * * @param name a name for this message body - * @param cnt the content of the message + * @param content the content of the message */ - public void setContent(String name, String cnt) { - content = cnt; + public void setContent(String name, String content) { contentName = name; arguments.clear(); + + VelocityEngine templateEngine = new VelocityEngine(); + templateEngine.init(VELOCITY_PROPERTIES); + + StringResourceRepository repo = (StringResourceRepository) + templateEngine.getApplicationAttribute(RESOURCE_REPOSITORY_NAME); + repo.putStringResource(contentName, content); + // Turn content into a template. + template = templateEngine.getTemplate(contentName); } /** @@ -328,15 +332,20 @@ public void reset() { * {@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. + *

"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 */ public void send() throws MessagingException, IOException { + if (null == template) { + // No template -- no content -- PANIC!!! + throw new MessagingException("Email has no body"); + } + ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService(); @@ -356,36 +365,18 @@ public void send() throws MessagingException, IOException { MimeMessage message = new MimeMessage(session); // Set the recipients of the message - Iterator i = recipients.iterator(); - - while (i.hasNext()) { - message.addRecipient(Message.RecipientType.TO, new InternetAddress( - i.next())); + for (String recipient : recipients) { + message.addRecipient(Message.RecipientType.TO, + new InternetAddress(recipient)); } // Get headers defined by the template. String[] templateHeaders = config.getArrayProperty("mail.message.headers"); // Format the mail message body - VelocityEngine templateEngine = new VelocityEngine(); - templateEngine.init(VELOCITY_PROPERTIES); - VelocityContext vctx = new VelocityContext(); vctx.put("config", new UnmodifiableConfigurationService(config)); vctx.put("params", Collections.unmodifiableList(arguments)); - if (null == template) { - if (StringUtils.isBlank(content)) { - // No template and no content -- PANIC!!! - throw new MessagingException("Email has no body"); - } - // No existing template, so use a String of content. - StringResourceRepository repo = (StringResourceRepository) - templateEngine.getApplicationAttribute(RESOURCE_REPOSITORY_NAME); - repo.putStringResource(contentName, content); - // Turn content into a template. - template = templateEngine.getTemplate(contentName); - } - StringWriter writer = new StringWriter(); try { template.merge(vctx, writer); @@ -452,7 +443,8 @@ public void send() throws MessagingException, IOException { // add the stream messageBodyPart = new MimeBodyPart(); messageBodyPart.setDataHandler(new DataHandler( - new InputStreamDataSource(attachment.name,attachment.mimetype,attachment.is))); + new InputStreamDataSource(attachment.name, + attachment.mimetype, attachment.is))); messageBodyPart.setFileName(attachment.name); multipart.addBodyPart(messageBodyPart); } From b846c53baaeae1e19fbbafa3dc7ca724bcaf32c1 Mon Sep 17 00:00:00 2001 From: "David P. Steelman" Date: Mon, 3 Jul 2023 14:09:15 -0400 Subject: [PATCH 04/37] DS-8935. webui.browse.link CrossLinks - Fix for multiple exact matches Fixes #8935 when multiple exact match "webui.browse.link" configuration entries are present that point to different indexes. Modified the code to return the index associated with the given metadata (which is used as the key in the hash map), instead of the key from the keySet (which may not actually be the metadata value being searched for). https://github.com/DSpace/DSpace/issues/8935 --- .../java/org/dspace/browse/CrossLinks.java | 2 +- .../org/dspace/browse/CrossLinksTest.java | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 dspace-api/src/test/java/org/dspace/browse/CrossLinksTest.java diff --git a/dspace-api/src/main/java/org/dspace/browse/CrossLinks.java b/dspace-api/src/main/java/org/dspace/browse/CrossLinks.java index 1ce2e558866d..ec4cb199ea1d 100644 --- a/dspace-api/src/main/java/org/dspace/browse/CrossLinks.java +++ b/dspace-api/src/main/java/org/dspace/browse/CrossLinks.java @@ -108,7 +108,7 @@ public String findLinkType(String metadata) { } else { // Exact match, if the key field has no .* wildcard if (links.containsKey(metadata)) { - return links.get(key); + return links.get(metadata); } } } diff --git a/dspace-api/src/test/java/org/dspace/browse/CrossLinksTest.java b/dspace-api/src/test/java/org/dspace/browse/CrossLinksTest.java new file mode 100644 index 000000000000..83aab72d904e --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/browse/CrossLinksTest.java @@ -0,0 +1,103 @@ +/** + * 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.browse; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.dspace.AbstractDSpaceTest; +import org.dspace.services.ConfigurationService; +import org.dspace.utils.DSpace; +import org.junit.Before; +import org.junit.Test; + +/** + * Test class for {@link CrossLinks} + */ +public class CrossLinksTest extends AbstractDSpaceTest { + protected ConfigurationService configurationService; + + + @Before + public void setUp() { + configurationService = new DSpace().getConfigurationService(); + } + + @Test + public void testFindLinkType_Null() throws Exception { + CrossLinks crossLinks = new CrossLinks(); + assertNull(crossLinks.findLinkType(null)); + } + + @Test + public void testFindLinkType_NoMatch() throws Exception { + CrossLinks crossLinks = new CrossLinks(); + String metadataField = "foo.bar.baz.does.not.exist"; + assertNull(crossLinks.findLinkType(metadataField)); + } + + @Test + public void testFindLinkType_WildcardMatch() throws Exception { + configurationService.setProperty("webui.browse.link.1", "author:dc.contributor.*"); + CrossLinks crossLinks = new CrossLinks(); + + String metadataField = "dc.contributor.author"; + assertEquals("author",crossLinks.findLinkType(metadataField)); + } + + @Test + public void testFindLinkType_SingleExactMatch_Author() throws Exception { + configurationService.setProperty("webui.browse.link.1", "author:dc.contributor.author"); + CrossLinks crossLinks = new CrossLinks(); + + assertEquals("type",crossLinks.findLinkType("dc.genre")); + assertEquals("author",crossLinks.findLinkType("dc.contributor.author")); + } + + @Test + public void testFindLinkType_SingleExactMatch_Type() throws Exception { + configurationService.setProperty("webui.browse.link.1", "type:dc.genre"); + CrossLinks crossLinks = new CrossLinks(); + + assertEquals("type",crossLinks.findLinkType("dc.genre")); + } + + @Test + public void testFindLinkType_MultipleExactMatches_DifferentIndexes() throws Exception { + configurationService.setProperty("webui.browse.link.1", "author:dc.contributor.author"); + configurationService.setProperty("webui.browse.link.2", "type:dc.genre"); + CrossLinks crossLinks = new CrossLinks(); + + assertEquals("author",crossLinks.findLinkType("dc.contributor.author")); + assertEquals("type",crossLinks.findLinkType("dc.genre")); + } + + @Test + public void testFindLinkType_MultipleWildcardMatches_DifferentIndexes() throws Exception { + configurationService.setProperty("webui.browse.link.1", "author:dc.contributor.*"); + configurationService.setProperty("webui.browse.link.2", "subject:dc.subject.*"); + CrossLinks crossLinks = new CrossLinks(); + + assertEquals("author",crossLinks.findLinkType("dc.contributor.author")); + assertEquals("subject",crossLinks.findLinkType("dc.subject.lcsh")); + } + + @Test + public void testFindLinkType_MultiplExactAndWildcardMatches_DifferentIndexes() throws Exception { + configurationService.setProperty("webui.browse.link.1", "author:dc.contributor.*"); + configurationService.setProperty("webui.browse.link.2", "subject:dc.subject.*"); + configurationService.setProperty("webui.browse.link.3", "type:dc.genre"); + configurationService.setProperty("webui.browse.link.4", "dateissued:dc.date.issued"); + CrossLinks crossLinks = new CrossLinks(); + + assertEquals("author",crossLinks.findLinkType("dc.contributor.author")); + assertEquals("subject",crossLinks.findLinkType("dc.subject.lcsh")); + assertEquals("type",crossLinks.findLinkType("dc.genre")); + assertEquals("dateissued",crossLinks.findLinkType("dc.date.issued")); + } +} From c72facbd74481af2656f1dd6a719b88da75e7419 Mon Sep 17 00:00:00 2001 From: "max.nuding" Date: Thu, 6 Jul 2023 09:17:59 +0200 Subject: [PATCH 05/37] Fix #8933: Only add the base statistic core if it hasn't already been added --- .../java/org/dspace/statistics/SolrLoggerServiceImpl.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java b/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java index 7853c3e11abf..9f34a4204721 100644 --- a/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java @@ -1691,6 +1691,14 @@ protected synchronized void initSolrYearCores() { statisticYearCores .add(baseSolrUrl.replace("http://", "").replace("https://", "") + statCoreName); } + var baseCore = ((HttpSolrClient) solr) + .getBaseURL() + .replace("http://", "") + .replace("https://", ""); + if (!statisticYearCores.contains(baseCore)) { + //Also add the core containing the current year, if it hasn't been added already + statisticYearCores.add(baseCore); + } //Also add the core containing the current year ! statisticYearCores.add(((HttpSolrClient) solr) .getBaseURL() From 4b0601e495795782db8877190de5b8ae0cbe07ee Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Tue, 11 Jul 2023 16:52:20 +0200 Subject: [PATCH 06/37] remove obsolete code fragments --- .../dspace/discovery/indexobject/ItemIndexFactoryImpl.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java index 005f9b42472e..39947146ddd8 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java @@ -172,13 +172,6 @@ public SolrInputDocument buildDocument(Context context, IndexableItem indexableI addNamedResourceTypeIndex(doc, acvalue); } - // write the index and close the inputstreamreaders - try { - log.info("Wrote Item: " + item.getID() + " to Index"); - } catch (RuntimeException e) { - log.error("Error while writing item to discovery index: " + item.getID() + " message:" - + e.getMessage(), e); - } return doc; } From 4cf019f6503b6f9db73ee40b86d71ac90b35dc06 Mon Sep 17 00:00:00 2001 From: Agustina Martinez Date: Fri, 14 Jul 2023 11:06:35 +0100 Subject: [PATCH 07/37] Update FullTextContentStreams.java Fix NPE if bitstream is null --- .../dspace/discovery/FullTextContentStreams.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/FullTextContentStreams.java b/dspace-api/src/main/java/org/dspace/discovery/FullTextContentStreams.java index ee220e5a4fdf..6d0c57c62855 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/FullTextContentStreams.java +++ b/dspace-api/src/main/java/org/dspace/discovery/FullTextContentStreams.java @@ -77,13 +77,19 @@ private void buildFullTextList(Item parentItem) { // a-ha! grab the text out of the bitstreams List bitstreams = myBundle.getBitstreams(); + log.debug("Processing full-text bitstreams. Item handle: " + sourceInfo); + for (Bitstream fulltextBitstream : emptyIfNull(bitstreams)) { fullTextStreams.add(new FullTextBitstream(sourceInfo, fulltextBitstream)); - log.debug("Added BitStream: " - + fulltextBitstream.getStoreNumber() + " " - + fulltextBitstream.getSequenceID() + " " - + fulltextBitstream.getName()); + if (fulltextBitstream != null) { + log.debug("Added BitStream: " + + fulltextBitstream.getStoreNumber() + " " + + fulltextBitstream.getSequenceID() + " " + + fulltextBitstream.getName()); + } else { + log.error("Found a NULL bitstream when processing full-text files: item handle:" + sourceInfo); + } } } } From e645d0fa25195096ca9d60ecfbd2b141967556a2 Mon Sep 17 00:00:00 2001 From: Agustina Martinez Date: Fri, 14 Jul 2023 16:17:22 +0100 Subject: [PATCH 08/37] Update FullTextContentStreams.java Add additional NPE checks --- .../java/org/dspace/discovery/FullTextContentStreams.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/FullTextContentStreams.java b/dspace-api/src/main/java/org/dspace/discovery/FullTextContentStreams.java index 6d0c57c62855..21468def6866 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/FullTextContentStreams.java +++ b/dspace-api/src/main/java/org/dspace/discovery/FullTextContentStreams.java @@ -76,7 +76,6 @@ private void buildFullTextList(Item parentItem) { if (StringUtils.equals(FULLTEXT_BUNDLE, myBundle.getName())) { // a-ha! grab the text out of the bitstreams List bitstreams = myBundle.getBitstreams(); - log.debug("Processing full-text bitstreams. Item handle: " + sourceInfo); for (Bitstream fulltextBitstream : emptyIfNull(bitstreams)) { @@ -164,16 +163,16 @@ public FullTextBitstream(final String parentHandle, final Bitstream file) { } public String getContentType(final Context context) throws SQLException { - BitstreamFormat format = bitstream.getFormat(context); + BitstreamFormat format = bitstream != null ? bitstream.getFormat(context) : null; return format == null ? null : StringUtils.trimToEmpty(format.getMIMEType()); } public String getFileName() { - return StringUtils.trimToEmpty(bitstream.getName()); + return bitstream != null ? StringUtils.trimToEmpty(bitstream.getName()) : null; } public long getSize() { - return bitstream.getSizeBytes(); + return bitstream != null ? bitstream.getSizeBytes() : -1; } public InputStream getInputStream() throws SQLException, IOException, AuthorizeException { From acf376db346d2f3b979b91c4e007cf39f0ab8d18 Mon Sep 17 00:00:00 2001 From: Agustina Martinez Date: Sun, 16 Jul 2023 20:42:03 +0100 Subject: [PATCH 09/37] Update ItemUtils.java Prevent npe if bitstream is null --- dspace-oai/src/main/java/org/dspace/xoai/util/ItemUtils.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dspace-oai/src/main/java/org/dspace/xoai/util/ItemUtils.java b/dspace-oai/src/main/java/org/dspace/xoai/util/ItemUtils.java index 955c3a78c392..35bef8c8d77f 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/util/ItemUtils.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/util/ItemUtils.java @@ -103,6 +103,11 @@ private static Element createBundlesElement(Context context, Item item) throws S bundle.getElement().add(bitstreams); List bits = b.getBitstreams(); for (Bitstream bit : bits) { + // Check if bitstream is null and log the error + if (bit == null) { + log.error("Null bitstream found, check item uuid: " + item.getID()); + break; + } Element bitstream = create("bitstream"); bitstreams.getElement().add(bitstream); String url = ""; From aa35a47add5565a9302d276da2ceb22b8dbc320f Mon Sep 17 00:00:00 2001 From: corrado lombardi Date: Wed, 19 Jul 2023 12:58:36 +0200 Subject: [PATCH 10/37] [DURACOM-179] replaced 'null' value with exception actual value in sendErrorResponse method calls having 'null' --- .../exception/DSpaceApiExceptionControllerAdvice.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java index 4ad1e479348f..a65ea13bc2c0 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java @@ -132,7 +132,7 @@ protected void handleUnprocessableEntityException(HttpServletRequest request, Ht Exception ex) throws IOException { //422 is not defined in HttpServletResponse. Its meaning is "Unprocessable Entity". //Using the value from HttpStatus. - sendErrorResponse(request, response, null, + sendErrorResponse(request, response, ex, "Unprocessable or invalid entity", HttpStatus.UNPROCESSABLE_ENTITY.value()); } @@ -140,7 +140,7 @@ protected void handleUnprocessableEntityException(HttpServletRequest request, Ht @ExceptionHandler( {InvalidSearchRequestException.class}) protected void handleInvalidSearchRequestException(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException { - sendErrorResponse(request, response, null, + sendErrorResponse(request, response, ex, "Invalid search request", HttpStatus.UNPROCESSABLE_ENTITY.value()); } @@ -180,7 +180,7 @@ protected void handleCustomUnprocessableEntityException(HttpServletRequest reque TranslatableException ex) throws IOException { Context context = ContextUtil.obtainContext(request); sendErrorResponse( - request, response, null, ex.getLocalizedMessage(context), HttpStatus.UNPROCESSABLE_ENTITY.value() + request, response, (Exception) ex, ex.getLocalizedMessage(context), HttpStatus.UNPROCESSABLE_ENTITY.value() ); } @@ -188,7 +188,7 @@ protected void handleCustomUnprocessableEntityException(HttpServletRequest reque protected void ParameterConversionException(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException { // we want the 400 status for missing parameters, see https://jira.lyrasis.org/browse/DS-4428 - sendErrorResponse(request, response, null, + sendErrorResponse(request, response, ex, "A required parameter is invalid", HttpStatus.BAD_REQUEST.value()); } @@ -197,7 +197,7 @@ protected void ParameterConversionException(HttpServletRequest request, HttpServ protected void MissingParameterException(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException { // we want the 400 status for missing parameters, see https://jira.lyrasis.org/browse/DS-4428 - sendErrorResponse(request, response, null, + sendErrorResponse(request, response, ex, "A required parameter is missing", HttpStatus.BAD_REQUEST.value()); } From c004a33c9dd1224d23de3ca23b371e5d8e258a22 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 24 Jul 2023 11:08:15 -0500 Subject: [PATCH 11/37] Replace all old docker "dspace-7_x" tags with "latest" --- Dockerfile | 5 ++-- Dockerfile.cli | 5 ++-- Dockerfile.test | 5 ++-- docker-compose-cli.yml | 2 +- docker-compose.yml | 6 ++--- dspace/src/main/docker-compose/README.md | 4 +-- .../src/main/docker-compose/db.entities.yml | 2 +- dspace/src/main/docker-compose/db.restore.yml | 2 +- .../docker-compose/docker-compose-angular.yml | 2 +- dspace/src/main/docker/README.md | 26 +++++++++---------- 10 files changed, 31 insertions(+), 28 deletions(-) diff --git a/Dockerfile b/Dockerfile index f1ff6adf5ac5..664cba89faea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,15 @@ # This image will be published as dspace/dspace # See https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker for usage details # -# - note: default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x +# - note: default tag for branch: dspace/dspace: dspace/dspace:latest # This Dockerfile uses JDK11 by default, but has also been tested with JDK17. # To build with JDK17, use "--build-arg JDK_VERSION=17" ARG JDK_VERSION=11 +ARG DSPACE_VERSION=latest # Step 1 - Run Maven Build -FROM dspace/dspace-dependencies:dspace-7_x as build +FROM dspace/dspace-dependencies:${DSPACE_VERSION} as build ARG TARGET_DIR=dspace-installer WORKDIR /app # The dspace-installer directory will be written to /install diff --git a/Dockerfile.cli b/Dockerfile.cli index 62e83b79ef02..d54978375e54 100644 --- a/Dockerfile.cli +++ b/Dockerfile.cli @@ -1,14 +1,15 @@ # This image will be published as dspace/dspace-cli # See https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker for usage details # -# - note: default tag for branch: dspace/dspace-cli: dspace/dspace-cli:dspace-7_x +# - note: default tag for branch: dspace/dspace-cli: dspace/dspace-cli:latest # This Dockerfile uses JDK11 by default, but has also been tested with JDK17. # To build with JDK17, use "--build-arg JDK_VERSION=17" ARG JDK_VERSION=11 +ARG DSPACE_VERSION=latest # Step 1 - Run Maven Build -FROM dspace/dspace-dependencies:dspace-7_x as build +FROM dspace/dspace-dependencies:${DSPACE_VERSION} as build ARG TARGET_DIR=dspace-installer WORKDIR /app # The dspace-installer directory will be written to /install diff --git a/Dockerfile.test b/Dockerfile.test index 4e9b2b5b4343..16a04d00025f 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -1,16 +1,17 @@ # This image will be published as dspace/dspace # See https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker for usage details # -# - note: default tag for branch: dspace/dspace: dspace/dspace:dspace-7_x-test +# - note: default tag for branch: dspace/dspace: dspace/dspace:latest-test # # This image is meant for TESTING/DEVELOPMENT ONLY as it deploys the old v6 REST API under HTTP (not HTTPS) # This Dockerfile uses JDK11 by default, but has also been tested with JDK17. # To build with JDK17, use "--build-arg JDK_VERSION=17" ARG JDK_VERSION=11 +ARG DSPACE_VERSION=latest # Step 1 - Run Maven Build -FROM dspace/dspace-dependencies:dspace-7_x as build +FROM dspace/dspace-dependencies:${DSPACE_VERSION} as build ARG TARGET_DIR=dspace-installer WORKDIR /app # The dspace-installer directory will be written to /install diff --git a/docker-compose-cli.yml b/docker-compose-cli.yml index 9c66fed6835b..7dbdde370378 100644 --- a/docker-compose-cli.yml +++ b/docker-compose-cli.yml @@ -2,7 +2,7 @@ version: "3.7" services: dspace-cli: - image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-dspace-7_x}" + image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-latest}" container_name: dspace-cli build: context: . diff --git a/docker-compose.yml b/docker-compose.yml index 36ba6af2c981..e623d9607931 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,7 +28,7 @@ services: # proxies.trusted.ipranges: This setting is required for a REST API running in Docker to trust requests # from the host machine. This IP range MUST correspond to the 'dspacenet' subnet defined above. proxies__P__trusted__P__ipranges: '172.23.0' - image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-dspace-7_x-test}" + image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-latest-test}" build: context: . dockerfile: Dockerfile.test @@ -66,7 +66,7 @@ services: dspacedb: container_name: dspacedb # Uses a custom Postgres image with pgcrypto installed - image: "${DOCKER_OWNER:-dspace}/dspace-postgres-pgcrypto:${DSPACE_VER:-dspace-7_x}" + image: "${DOCKER_OWNER:-dspace}/dspace-postgres-pgcrypto:${DSPACE_VER:-latest}" build: # Must build out of subdirectory to have access to install script for pgcrypto context: ./dspace/src/main/docker/dspace-postgres-pgcrypto/ @@ -86,7 +86,7 @@ services: # DSpace Solr container dspacesolr: container_name: dspacesolr - image: "${DOCKER_OWNER:-dspace}/dspace-solr:${DSPACE_VER:-dspace-7_x}" + image: "${DOCKER_OWNER:-dspace}/dspace-solr:${DSPACE_VER:-latest}" build: context: . dockerfile: ./dspace/src/main/docker/dspace-solr/Dockerfile diff --git a/dspace/src/main/docker-compose/README.md b/dspace/src/main/docker-compose/README.md index 35a6e6055433..8660a9796c7d 100644 --- a/dspace/src/main/docker-compose/README.md +++ b/dspace/src/main/docker-compose/README.md @@ -268,8 +268,8 @@ Here's how to fix those issues by migrating your old Postgres data to the new ve * Pull down an older version of the image from Dockerhub (using a tag) * Or, temporarily rebuild your local image with the old version of Postgres. For example: ``` - # This command will rebuild using PostgreSQL v11 & tag it locally as "dspace-7_x" - docker build --build-arg POSTGRES_VERSION=11 -t dspace/dspace-postgres-pgcrypto:dspace-7_x ./dspace/src/main/docker/dspace-postgres-pgcrypto/ + # This command will rebuild using PostgreSQL v11 & tag it locally as "latest" + docker build --build-arg POSTGRES_VERSION=11 -t dspace/dspace-postgres-pgcrypto:latest ./dspace/src/main/docker/dspace-postgres-pgcrypto/ # Then restart container with that image docker-compose -p d7 up -d ``` diff --git a/dspace/src/main/docker-compose/db.entities.yml b/dspace/src/main/docker-compose/db.entities.yml index 32c54a5d0bd1..943f0732c69a 100644 --- a/dspace/src/main/docker-compose/db.entities.yml +++ b/dspace/src/main/docker-compose/db.entities.yml @@ -10,7 +10,7 @@ version: "3.7" services: dspacedb: - image: dspace/dspace-postgres-pgcrypto:dspace-7_x-loadsql + image: dspace/dspace-postgres-pgcrypto:${DSPACE_VER:-latest}-loadsql environment: # This SQL is available from https://github.com/DSpace-Labs/AIP-Files/releases/tag/demo-entities-data - LOADSQL=https://github.com/DSpace-Labs/AIP-Files/releases/download/demo-entities-data/dspace7-entities-data.sql diff --git a/dspace/src/main/docker-compose/db.restore.yml b/dspace/src/main/docker-compose/db.restore.yml index fc2f30b9d8e0..5646370a91ef 100644 --- a/dspace/src/main/docker-compose/db.restore.yml +++ b/dspace/src/main/docker-compose/db.restore.yml @@ -14,7 +14,7 @@ version: "3.7" # This can be used to restore a "dspacedb" container from a pg_dump, or during upgrade to a new version of PostgreSQL. services: dspacedb: - image: dspace/dspace-postgres-pgcrypto:dspace-7_x-loadsql + image: dspace/dspace-postgres-pgcrypto:${DSPACE_VER:-latest}-loadsql environment: # Location where the dump SQL file will be available on the running container - LOCALSQL=/tmp/pgdump.sql diff --git a/dspace/src/main/docker-compose/docker-compose-angular.yml b/dspace/src/main/docker-compose/docker-compose-angular.yml index 00dde2e83187..6690fb8bc526 100644 --- a/dspace/src/main/docker-compose/docker-compose-angular.yml +++ b/dspace/src/main/docker-compose/docker-compose-angular.yml @@ -23,7 +23,7 @@ services: DSPACE_REST_HOST: localhost DSPACE_REST_PORT: 8080 DSPACE_REST_NAMESPACE: /server - image: dspace/dspace-angular:dspace-7_x + image: dspace/dspace-angular:${DSPACE_VER:-latest} networks: dspacenet: ports: diff --git a/dspace/src/main/docker/README.md b/dspace/src/main/docker/README.md index ac1b4cb9236b..bee59ad876ea 100644 --- a/dspace/src/main/docker/README.md +++ b/dspace/src/main/docker/README.md @@ -16,7 +16,7 @@ Caching these Maven dependencies provides a speed increase to all later builds b are only downloaded once. ``` -docker build -t dspace/dspace-dependencies:dspace-7_x -f Dockerfile.dependencies . +docker build -t dspace/dspace-dependencies:latest -f Dockerfile.dependencies . ``` This image is built *automatically* after each commit is made to the `main` branch. @@ -25,7 +25,7 @@ A corresponding image exists for DSpace 4-6. Admins to our DockerHub repo can manually publish with the following command. ``` -docker push dspace/dspace-dependencies:dspace-7_x +docker push dspace/dspace-dependencies:latest ``` ## Dockerfile.test (in root folder) @@ -37,7 +37,7 @@ This image deploys two DSpace webapps to Tomcat running in Docker: This image also sets up debugging in Tomcat for development. ``` -docker build -t dspace/dspace:dspace-7_x-test -f Dockerfile.test . +docker build -t dspace/dspace:latest-test -f Dockerfile.test . ``` This image is built *automatically* after each commit is made to the `main` branch. @@ -46,7 +46,7 @@ A corresponding image exists for DSpace 4-6. Admins to our DockerHub repo can manually publish with the following command. ``` -docker push dspace/dspace:dspace-7_x-test +docker push dspace/dspace:latest-test ``` ## Dockerfile (in root folder) @@ -56,7 +56,7 @@ This image deploys one DSpace webapp to Tomcat running in Docker: 1. The DSpace 7 REST API (at `http://localhost:8080/server`) ``` -docker build -t dspace/dspace:dspace-7_x -f Dockerfile . +docker build -t dspace/dspace:latest -f Dockerfile . ``` This image is built *automatically* after each commit is made to the `main` branch. @@ -65,14 +65,14 @@ A corresponding image exists for DSpace 4-6. Admins to our DockerHub repo can publish with the following command. ``` -docker push dspace/dspace:dspace-7_x +docker push dspace/dspace:latest ``` ## Dockerfile.cli (in root folder) This Dockerfile builds a DSpace 7 CLI (command line interface) image, which can be used to run DSpace's commandline tools via Docker. ``` -docker build -t dspace/dspace-cli:dspace-7_x -f Dockerfile.cli . +docker build -t dspace/dspace-cli:latest -f Dockerfile.cli . ``` This image is built *automatically* after each commit is made to the `main` branch. @@ -81,7 +81,7 @@ A corresponding image exists for DSpace 6. Admins to our DockerHub repo can publish with the following command. ``` -docker push dspace/dspace-cli:dspace-7_x +docker push dspace/dspace-cli:latest ``` ## ./dspace-postgres-pgcrypto/Dockerfile @@ -92,20 +92,20 @@ This image is built *automatically* after each commit is made to the `main` bran How to build manually: ``` cd dspace/src/main/docker/dspace-postgres-pgcrypto -docker build -t dspace/dspace-postgres-pgcrypto:dspace-7_x . +docker build -t dspace/dspace-postgres-pgcrypto:latest . ``` It is also possible to change the version of PostgreSQL or the PostgreSQL user's password during the build: ``` cd dspace/src/main/docker/dspace-postgres-pgcrypto -docker build -t dspace/dspace-postgres-pgcrypto:dspace-7_x --build-arg POSTGRES_VERSION=11 --build-arg POSTGRES_PASSWORD=mypass . +docker build -t dspace/dspace-postgres-pgcrypto:latest --build-arg POSTGRES_VERSION=11 --build-arg POSTGRES_PASSWORD=mypass . ``` A copy of this file exists in the DSpace 6 branch. A specialized version of this file exists for DSpace 4 in DSpace-Docker-Images. Admins to our DockerHub repo can (manually) publish with the following command. ``` -docker push dspace/dspace-postgres-pgcrypto:dspace-7_x +docker push dspace/dspace-postgres-pgcrypto:latest ``` ## ./dspace-postgres-pgcrypto-curl/Dockerfile @@ -118,7 +118,7 @@ This image is built *automatically* after each commit is made to the `main` bran How to build manually: ``` cd dspace/src/main/docker/dspace-postgres-pgcrypto-curl -docker build -t dspace/dspace-postgres-pgcrypto:dspace-7_x-loadsql . +docker build -t dspace/dspace-postgres-pgcrypto:latest-loadsql . ``` Similar to `dspace-postgres-pgcrypto` above, you can also modify the version of PostgreSQL or the PostgreSQL user's password. @@ -128,7 +128,7 @@ A copy of this file exists in the DSpace 6 branch. Admins to our DockerHub repo can (manually) publish with the following command. ``` -docker push dspace/dspace-postgres-pgcrypto:dspace-7_x-loadsql +docker push dspace/dspace-postgres-pgcrypto:latest-loadsql ``` ## ./dspace-shibboleth/Dockerfile From f6a898c3d13360286c416b2588ab0447d9e3d81b Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 27 Jul 2023 16:55:42 -0500 Subject: [PATCH 12/37] Add action to automatically create a port PR when specified --- .../workflows/port_merged_pull_request.yml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/port_merged_pull_request.yml diff --git a/.github/workflows/port_merged_pull_request.yml b/.github/workflows/port_merged_pull_request.yml new file mode 100644 index 000000000000..418498fa4499 --- /dev/null +++ b/.github/workflows/port_merged_pull_request.yml @@ -0,0 +1,38 @@ +# This workflow will attempt to port a merged pull request to +# the branch specified in a "port to" label (if exists) +name: Port merged Pull Request + +# Only run for merged PRs against the "main" or maintenance branches +# We allow this to run for `pull_request_target` so that github secrets are available +# (This is required when the PR comes from a forked repo) +on: + pull_request_target: + types: [ closed ] + branches: + - main + - 'dspace-**' + +permissions: + contents: write # so action can add comments + pull-requests: write # so action can create pull requests + +jobs: + port_pr: + runs-on: ubuntu-latest + # Don't run on closed *unmerged* pull requests + if: github.event.pull_request.merged + steps: + # Checkout code + - uses: actions/checkout@v3 + # Port PR to other branch (ONLY if labeled with "port to") + # See https://github.com/korthout/backport-action + - name: Create backport pull requests + uses: korthout/backport-action@v1 + with: + # Trigger based on a "port to [branch]" label on PR + # (This label must specify the branch name to port to) + label_pattern: '^port to ([^ ]+)$' + # Title to add to the (newly created) port PR + pull_title: '[Port ${target_branch}] ${pull_title}' + # Description to add to the (newly created) port PR + pull_description: 'Port of #${pull_number} by @${pull_author} to `${target_branch}`.' \ No newline at end of file From 16c46c49797cf4a15b8ef51efdd365610bdf73ab Mon Sep 17 00:00:00 2001 From: Alan Orth Date: Wed, 26 Jul 2023 21:26:04 +0300 Subject: [PATCH 13/37] dspace.cfg: remove old webui.itemlist properties These properties are no longer used in DSpace 7: webui.itemlist.widths webui.itemlist.*.widths webui.itemlist.tablewidth --- dspace/config/dspace.cfg | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index cafd37931fd4..c37cfea0b196 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -1472,11 +1472,6 @@ log.report.dir = ${dspace.dir}/log # # webui.itemlist.columns = thumbnail, dc.date.issued(date), dc.title, dc.contributor.* # -# You can customise the width of each column with the following line - you can have numbers (pixels) -# or percentages. For the 'thumbnail' column, a setting of '*' will use the max width specified -# for browse thumbnails (webui.browse.thumbnail.maxwidth, thumbnail.maxwidth) -# webui.itemlist.widths = *, 130, 60%, 40% - # Additionally, you can override the DC fields used on the listing page for # a given browse index and/or sort option. As a sort option or index may be defined # on a field that isn't normally included in the list, this allows you to display @@ -1502,14 +1497,6 @@ log.report.dir = ${dspace.dir}/log # and thumbnails in the item list # # webui.itemlist.dateaccessioned.columns = thumbnail, dc.date.accessioned(date), dc.title, dc.contributor.* -# -# As above, you can customise the width of the columns for each configured column list, substituting '.widths' for -# '.columns' in the property name. See the setting for webui.itemlist.widths for more details -# webui.itemlist.dateaccessioned.widths = *, 130, 60%, 40% - -# You can also set the overall size of the item list table with the following setting. It can lead to faster -# table rendering when used with the column widths above, but not generally recommended. -# webui.itemlist.tablewidth = 100% ##### SFX Server (OpenURL) ##### From 213a546486073f09e73d91d014c489ed300bf59d Mon Sep 17 00:00:00 2001 From: Alan Orth Date: Wed, 26 Jul 2023 21:42:16 +0300 Subject: [PATCH 14/37] dspace.cfg: remove old webui.browse.thumbnail.show property The webui.browse.thumbnail.show property is no longer used as of DSpace 7. Also remove subsequent references to adding thumbnails to item view columns since these are from legacy DSpace. --- dspace/config/dspace.cfg | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index c37cfea0b196..c7f1cb80a978 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -1460,9 +1460,6 @@ log.report.dir = ${dspace.dir}/log # fields at least the date and title fields as specified by the # webui.browse.index.* configuration options below. # -# If you have enabled thumbnails (webui.browse.thumbnail.show), you must also -# include a 'thumbnail' entry in your columns - this is where the thumbnail will be displayed -# # If you want to mark each item include a 'mark_[value]' (without the brackets - replace the word 'value' with anything that # has a meaning for your mark) entry in your columns - this is where the icon will be displayed. # Do not forget to add a Spring bean with id = "org.dspace.app.itemmarking.ItemMarkingExtractor.[value]" @@ -1470,7 +1467,7 @@ log.report.dir = ${dspace.dir}/log # You can add more than one 'mark_[value]' options (with different value) in case you need to mark items more than one time for # different purposes. Remember to add the respective beans in file 'config/spring/api/item-marking.xml'. # -# webui.itemlist.columns = thumbnail, dc.date.issued(date), dc.title, dc.contributor.* +# webui.itemlist.columns = dc.date.issued(date), dc.title, dc.contributor.* # # Additionally, you can override the DC fields used on the listing page for # a given browse index and/or sort option. As a sort option or index may be defined @@ -1489,14 +1486,6 @@ log.report.dir = ${dspace.dir}/log # In the last case, a sort option name will always take precedence over a browse # index name. Note also, that for any additional columns you list, you will need to # ensure there is an itemlist. entry in the messages file. -# -# The following example would display the date of accession in place of the issue date -# whenever the dateaccessioned browse index or sort option is selected. -# -# Just like webui.itemlist.columns, you will need to include a 'thumbnail' entry to display -# and thumbnails in the item list -# -# webui.itemlist.dateaccessioned.columns = thumbnail, dc.date.accessioned(date), dc.title, dc.contributor.* ##### SFX Server (OpenURL) ##### From 35f72bc9d0c1a01aa0b9313216bbbe63e6960a81 Mon Sep 17 00:00:00 2001 From: Alan Orth Date: Wed, 26 Jul 2023 21:45:42 +0300 Subject: [PATCH 15/37] dspace.cfg: remove old webui.itemlist.browse.* property The webui.itemlist.browse.* properties are no longer used in DSpace 7. --- dspace/config/dspace.cfg | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index c7f1cb80a978..1feaf05cda30 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -1478,14 +1478,8 @@ log.report.dir = ${dspace.dir}/log # they are listed below is the priority in which they will be used (so a combination # of an index name and sort name will take precedence over just the browse name). # -# webui.itemlist.browse..sort..columns # webui.itemlist.sort..columns -# webui.itemlist.browse..columns # webui.itemlist..columns -# -# In the last case, a sort option name will always take precedence over a browse -# index name. Note also, that for any additional columns you list, you will need to -# ensure there is an itemlist. entry in the messages file. ##### SFX Server (OpenURL) ##### From 22974e982c99b7faa9d287ddc5bef4715f19849a Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Fri, 28 Jul 2023 10:50:07 -0400 Subject: [PATCH 16/37] On failure log the name of the assetstore file and trace causes of exception. --- .../mediafilter/MediaFilterServiceImpl.java | 12 +++--- .../java/org/dspace/util/ThrowableUtils.java | 41 +++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 dspace-api/src/main/java/org/dspace/util/ThrowableUtils.java diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java index e2c6c9c5db06..1a8c2ddd3ea4 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java @@ -40,6 +40,7 @@ import org.dspace.eperson.service.GroupService; import org.dspace.scripts.handler.DSpaceRunnableHandler; import org.dspace.services.ConfigurationService; +import org.dspace.util.ThrowableUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; @@ -240,8 +241,9 @@ public boolean filterBitstream(Context context, Item myItem, sb.append("\tFile Size: ").append(size); sb.append("\tChecksum: ").append(checksum); sb.append("\tAsset Store: ").append(assetstore); + sb.append("\tInternal ID: ").append(myBitstream.getInternalId()); logError(sb.toString()); - logError(e.getMessage(), e); + logError(ThrowableUtils.formatCauseChain(e)); } } else if (filterClass instanceof SelfRegisterInputFormats) { // Filter implements self registration, so check to see if it should be applied @@ -319,10 +321,10 @@ public boolean processBitstream(Context context, Item item, Bitstream source, Fo // check if destination bitstream exists Bundle existingBundle = null; - List existingBitstreams = new ArrayList(); + List existingBitstreams = new ArrayList<>(); List bundles = itemService.getBundles(item, formatFilter.getBundleName()); - if (bundles.size() > 0) { + if (!bundles.isEmpty()) { // only finds the last matching bundle and all matching bitstreams in the proper bundle(s) for (Bundle bundle : bundles) { List bitstreams = bundle.getBitstreams(); @@ -337,7 +339,7 @@ public boolean processBitstream(Context context, Item item, Bitstream source, Fo } // if exists and overwrite = false, exit - if (!overWrite && (existingBitstreams.size() > 0)) { + if (!overWrite && (!existingBitstreams.isEmpty())) { if (!isQuiet) { logInfo("SKIPPED: bitstream " + source.getID() + " (item: " + item.getHandle() + ") because '" + newName + "' already exists"); @@ -370,7 +372,7 @@ public boolean processBitstream(Context context, Item item, Bitstream source, Fo } Bundle targetBundle; // bundle we're modifying - if (bundles.size() < 1) { + if (bundles.isEmpty()) { // create new bundle if needed targetBundle = bundleService.create(context, item, formatFilter.getBundleName()); } else { diff --git a/dspace-api/src/main/java/org/dspace/util/ThrowableUtils.java b/dspace-api/src/main/java/org/dspace/util/ThrowableUtils.java new file mode 100644 index 000000000000..7809e2048a07 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/util/ThrowableUtils.java @@ -0,0 +1,41 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.util; + +/** + * Things you wish {@link Throwable} or some logging package would do for you. + * + * @author mwood + */ +public class ThrowableUtils { + /** + * Utility class: do not instantiate. + */ + private ThrowableUtils() { } + + /** + * Trace a chain of {@code Throwable}s showing only causes. + * Less voluminous than a stack trace. Useful if you just want to know + * what caused third-party code to return an uninformative exception + * message. + * + * @param throwable the exception or whatever. + * @return list of messages from each {@code Throwable} in the chain, + * separated by '\n'. + */ + static public String formatCauseChain(Throwable throwable) { + StringBuilder trace = new StringBuilder(); + trace.append(throwable.getMessage()); + Throwable cause = throwable.getCause(); + while (null != cause) { + trace.append("\nCaused by: ").append(cause.getMessage()); + cause = cause.getCause(); + } + return trace.toString(); + } +} From d6b612fc5cf84fe6b7226649451b7b927ded8997 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Fri, 28 Jul 2023 11:23:20 -0400 Subject: [PATCH 17/37] Report Throwable's type too. --- dspace-api/src/main/java/org/dspace/util/ThrowableUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/util/ThrowableUtils.java b/dspace-api/src/main/java/org/dspace/util/ThrowableUtils.java index 7809e2048a07..e1502e89b514 100644 --- a/dspace-api/src/main/java/org/dspace/util/ThrowableUtils.java +++ b/dspace-api/src/main/java/org/dspace/util/ThrowableUtils.java @@ -33,7 +33,9 @@ static public String formatCauseChain(Throwable throwable) { trace.append(throwable.getMessage()); Throwable cause = throwable.getCause(); while (null != cause) { - trace.append("\nCaused by: ").append(cause.getMessage()); + trace.append("\nCaused by: ") + .append(cause.getClass().getCanonicalName()).append(' ') + .append(cause.getMessage()); cause = cause.getCause(); } return trace.toString(); From 2dc7c90e83867247df9004c54d27b5c551136283 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 28 Jul 2023 11:15:08 -0500 Subject: [PATCH 18/37] Run PR Port action as 'dspace-bot' to allow new PRs to trigger CI checks --- .github/workflows/port_merged_pull_request.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/port_merged_pull_request.yml b/.github/workflows/port_merged_pull_request.yml index 418498fa4499..6c491e41c21b 100644 --- a/.github/workflows/port_merged_pull_request.yml +++ b/.github/workflows/port_merged_pull_request.yml @@ -35,4 +35,10 @@ jobs: # Title to add to the (newly created) port PR pull_title: '[Port ${target_branch}] ${pull_title}' # Description to add to the (newly created) port PR - pull_description: 'Port of #${pull_number} by @${pull_author} to `${target_branch}`.' \ No newline at end of file + pull_description: 'Port of #${pull_number} by @${pull_author} to `${target_branch}`.' + # Copy all labels from original PR to (newly created) port PR + # NOTE: The labels matching 'label_pattern' are automatically excluded + copy_labels_pattern: '*' + # Use a personal access token (PAT) to create PR as 'dspace-bot' user. + # A PAT is required in order for the new PR to trigger its own actions (for CI checks) + github_token: ${{ secrets.PR_PORT_TOKEN }} \ No newline at end of file From 5bff43356fca0aa9ee78782f000c0d1a25a6cfbb Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 28 Jul 2023 11:15:42 -0500 Subject: [PATCH 19/37] Minor update to label_merge_conflicts to ignore any errors (seem random at this time) --- .github/workflows/label_merge_conflicts.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/label_merge_conflicts.yml b/.github/workflows/label_merge_conflicts.yml index 0c3b1a0f2a80..a023f4eef246 100644 --- a/.github/workflows/label_merge_conflicts.yml +++ b/.github/workflows/label_merge_conflicts.yml @@ -25,6 +25,8 @@ jobs: # See: https://github.com/prince-chrismc/label-merge-conflicts-action - name: Auto-label PRs with merge conflicts uses: prince-chrismc/label-merge-conflicts-action@v3 + # Ignore any failures -- may occur (randomly?) for older, outdated PRs. + continue-on-error: true # Add "merge conflict" label if a merge conflict is detected. Remove it when resolved. # Note, the authentication token is created automatically # See: https://docs.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token From 799528963e3c0391852ecbaf82ef21ec7d477342 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 28 Jul 2023 11:48:30 -0500 Subject: [PATCH 20/37] Fix typo. Config must be a valid regex --- .github/workflows/port_merged_pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/port_merged_pull_request.yml b/.github/workflows/port_merged_pull_request.yml index 6c491e41c21b..50faf3f88679 100644 --- a/.github/workflows/port_merged_pull_request.yml +++ b/.github/workflows/port_merged_pull_request.yml @@ -38,7 +38,7 @@ jobs: pull_description: 'Port of #${pull_number} by @${pull_author} to `${target_branch}`.' # Copy all labels from original PR to (newly created) port PR # NOTE: The labels matching 'label_pattern' are automatically excluded - copy_labels_pattern: '*' + copy_labels_pattern: '.*' # Use a personal access token (PAT) to create PR as 'dspace-bot' user. # A PAT is required in order for the new PR to trigger its own actions (for CI checks) github_token: ${{ secrets.PR_PORT_TOKEN }} \ No newline at end of file From 71cfe184a5b831f1cbc1d487f6ef32e04eb127b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jul 2023 17:38:04 +0000 Subject: [PATCH 21/37] Bump h2 from 2.1.214 to 2.2.220 Bumps [h2](https://github.com/h2database/h2database) from 2.1.214 to 2.2.220. - [Release notes](https://github.com/h2database/h2database/releases) - [Commits](https://github.com/h2database/h2database/compare/version-2.1.214...version-2.2.220) --- updated-dependencies: - dependency-name: com.h2database:h2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5dc53194b335..7822d4310998 100644 --- a/pom.xml +++ b/pom.xml @@ -1688,7 +1688,7 @@ com.h2database h2 - 2.1.214 + 2.2.220 test From bbe5df3f7dd4a33423fdf47702e23f3eb9ef821f Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Mon, 31 Jul 2023 09:55:09 -0400 Subject: [PATCH 22/37] More description on OutOfMemoryError too. --- .../mediafilter/MediaFilterServiceImpl.java | 50 +++++++++++++------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java index 1a8c2ddd3ea4..b50fb22355a3 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java @@ -10,6 +10,7 @@ import java.io.InputStream; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -226,23 +227,8 @@ public boolean filterBitstream(Context context, Item myItem, filtered = true; } } catch (Exception e) { - String handle = myItem.getHandle(); - List bundles = myBitstream.getBundles(); - long size = myBitstream.getSizeBytes(); - String checksum = myBitstream.getChecksum() + " (" + myBitstream.getChecksumAlgorithm() + ")"; - int assetstore = myBitstream.getStoreNumber(); - // Printout helpful information to find the errored bitstream. - StringBuilder sb = new StringBuilder("ERROR filtering, skipping bitstream:\n"); - sb.append("\tItem Handle: ").append(handle); - for (Bundle bundle : bundles) { - sb.append("\tBundle Name: ").append(bundle.getName()); - } - sb.append("\tFile Size: ").append(size); - sb.append("\tChecksum: ").append(checksum); - sb.append("\tAsset Store: ").append(assetstore); - sb.append("\tInternal ID: ").append(myBitstream.getInternalId()); - logError(sb.toString()); + logError(formatBitstreamDetails(myItem.getHandle(), myBitstream)); logError(ThrowableUtils.formatCauseChain(e)); } } else if (filterClass instanceof SelfRegisterInputFormats) { @@ -401,6 +387,7 @@ public boolean processBitstream(Context context, Item item, Bitstream source, Fo } catch (OutOfMemoryError oome) { logError("!!! OutOfMemoryError !!!"); + logError(formatBitstreamDetails(item.getHandle(), source)); } // we are overwriting, so remove old bitstream @@ -498,6 +485,37 @@ public boolean inSkipList(String identifier) { } } + /** + * Describe a Bitstream in detail. Format a single line of text with + * information such as Bitstore index, backing file ID, size, checksum, + * enclosing Item and Bundles. + * + * @param itemHandle Handle of the Item by which we found the Bitstream. + * @param bitstream the Bitstream to be described. + * @return Bitstream details. + */ + private String formatBitstreamDetails(String itemHandle, + Bitstream bitstream) { + List bundles; + try { + bundles = bitstream.getBundles(); + } catch (SQLException ex) { + logError("Unexpected error fetching Bundles", ex); + bundles = Collections.EMPTY_LIST; + } + StringBuilder sb = new StringBuilder("ERROR filtering, skipping bitstream:\n"); + sb.append("\tItem Handle: ").append(itemHandle); + for (Bundle bundle : bundles) { + sb.append("\tBundle Name: ").append(bundle.getName()); + } + sb.append("\tFile Size: ").append(bitstream.getSizeBytes()); + sb.append("\tChecksum: ").append(bitstream.getChecksum()) + .append(" (").append(bitstream.getChecksumAlgorithm()).append(')'); + sb.append("\tAsset Store: ").append(bitstream.getStoreNumber()); + sb.append("\tInternal ID: ").append(bitstream.getInternalId()); + return sb.toString(); + } + private void logInfo(String message) { if (handler != null) { handler.logInfo(message); From b71eee89c1e1dd7569e800e13eb8878548853ce6 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 2 Aug 2023 15:36:40 -0500 Subject: [PATCH 23/37] Enable entity type to submission form mapping by default --- dspace/config/item-submission.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dspace/config/item-submission.xml b/dspace/config/item-submission.xml index a6cd49bdf1e8..1060a3303119 100644 --- a/dspace/config/item-submission.xml +++ b/dspace/config/item-submission.xml @@ -55,9 +55,7 @@ - - - - - - PLEASE NOTICE THAT YOU WILL HAVE TO RESTART DSPACE - - - - - - - Uncomment if you intend to use them - --> - @@ -65,8 +63,6 @@ - --> - From 29a88d7e2dcfc36d2cd7991de3b84ef5f5623b63 Mon Sep 17 00:00:00 2001 From: Christian Bethge <54576195+ChrisBethgster@users.noreply.github.com> Date: Thu, 3 Aug 2023 13:01:12 +0200 Subject: [PATCH 24/37] #9006 fix referenced configuration file --- .../src/main/java/org/dspace/statistics/GeoIpService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/statistics/GeoIpService.java b/dspace-api/src/main/java/org/dspace/statistics/GeoIpService.java index 7f8a11e5ba13..40fea6cf54da 100644 --- a/dspace-api/src/main/java/org/dspace/statistics/GeoIpService.java +++ b/dspace-api/src/main/java/org/dspace/statistics/GeoIpService.java @@ -37,7 +37,7 @@ public class GeoIpService { public DatabaseReader getDatabaseReader() throws IllegalStateException { String dbPath = configurationService.getProperty("usage-statistics.dbfile"); if (StringUtils.isBlank(dbPath)) { - throw new IllegalStateException("The required 'dbfile' configuration is missing in solr-statistics.cfg!"); + throw new IllegalStateException("The required 'dbfile' configuration is missing in usage-statistics.cfg!"); } try { From 309b0b355e4bffd6a1be3e6341dd6d17f99892c8 Mon Sep 17 00:00:00 2001 From: Christian Bethge <54576195+ChrisBethgster@users.noreply.github.com> Date: Thu, 3 Aug 2023 13:04:03 +0200 Subject: [PATCH 25/37] #9006 fix referenced configuration file (Test) --- .../src/test/java/org/dspace/app/rest/HealthIndicatorsIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/HealthIndicatorsIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/HealthIndicatorsIT.java index 8c1c534de14c..0bb679339877 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/HealthIndicatorsIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/HealthIndicatorsIT.java @@ -67,7 +67,7 @@ public void testWithAdminUser() throws Exception { match("solrSearchCore", Status.UP, Map.of("status", 0, "detectedPathType", "root")), match("solrStatisticsCore", Status.UP, Map.of("status", 0, "detectedPathType", "root")), match("geoIp", UP_WITH_ISSUES_STATUS, - Map.of("reason", "The required 'dbfile' configuration is missing in solr-statistics.cfg!")) + Map.of("reason", "The required 'dbfile' configuration is missing in usage-statistics.cfg!")) ))); } From d44507d647dd0c96ab80bce6d9a7aeb6edfb5540 Mon Sep 17 00:00:00 2001 From: Max Nuding Date: Fri, 4 Aug 2023 08:39:03 +0200 Subject: [PATCH 26/37] Remove duplicate code --- .../java/org/dspace/statistics/SolrLoggerServiceImpl.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java b/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java index 9f34a4204721..19c79af34dcc 100644 --- a/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java @@ -1699,11 +1699,6 @@ protected synchronized void initSolrYearCores() { //Also add the core containing the current year, if it hasn't been added already statisticYearCores.add(baseCore); } - //Also add the core containing the current year ! - statisticYearCores.add(((HttpSolrClient) solr) - .getBaseURL() - .replace("http://", "") - .replace("https://", "")); } catch (IOException | SolrServerException e) { log.error(e.getMessage(), e); } From 8ae5ffbf9b41fe2ad4e1146eceeff47e6ba985a0 Mon Sep 17 00:00:00 2001 From: Christian Bethge Date: Mon, 7 Aug 2023 09:42:07 +0200 Subject: [PATCH 27/37] fix MissingOptionException on help --- .../dspace/app/launcher/ScriptLauncher.java | 14 ++++- .../org/dspace/scripts/DSpaceRunnable.java | 55 +++++++++++++++++-- .../configuration/ScriptConfiguration.java | 15 +++++ .../dspace/app/bulkedit/MetadataExportIT.java | 15 +++-- .../dspace/app/bulkedit/MetadataImportIT.java | 5 +- .../app/csv/CSVMetadataImportReferenceIT.java | 5 +- .../java/org/dspace/curate/CurationIT.java | 10 ++-- 7 files changed, 98 insertions(+), 21 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java index fcb2098bd066..e6df016613b9 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java @@ -21,6 +21,7 @@ import org.apache.logging.log4j.Logger; import org.dspace.core.Context; import org.dspace.scripts.DSpaceRunnable; +import org.dspace.scripts.DSpaceRunnable.StepResult; import org.dspace.scripts.configuration.ScriptConfiguration; import org.dspace.scripts.factory.ScriptServiceFactory; import org.dspace.scripts.handler.DSpaceRunnableHandler; @@ -145,9 +146,16 @@ public static int handleScript(String[] args, Document commandConfigs, private static int executeScript(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler, DSpaceRunnable script) { try { - script.initialize(args, dSpaceRunnableHandler, null); - script.run(); - return 0; + StepResult result = script.initialize(args, dSpaceRunnableHandler, null); + + if (StepResult.Continue.equals(result)) { + // only run the script, if the normal initialize is successful + script.run(); + } else { + // otherwise - for example the script is started with the help argument + } + + return 0; } catch (ParseException e) { script.printHelp(); e.printStackTrace(); diff --git a/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java b/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java index 2319aee31752..4f64f6973179 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java +++ b/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java @@ -35,6 +35,11 @@ public abstract class DSpaceRunnable implements R * The CommandLine object for the script that'll hold the information */ protected CommandLine commandLine; + + /** + * The minimal CommandLine object for the script that'll hold help information + */ + protected CommandLine helpCommandLine; /** * This EPerson identifier variable is the UUID of the EPerson that's running the script @@ -64,27 +69,64 @@ private void setHandler(DSpaceRunnableHandler dSpaceRunnableHandler) { * @param args The arguments given to the script * @param dSpaceRunnableHandler The DSpaceRunnableHandler object that defines from where the script was ran * @param currentUser + * @return the result of this step; StepResult.Continue: continue the normal process, initialize is successful; + * otherwise exit the process (the help or version is shown) * @throws ParseException If something goes wrong */ - public void initialize(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler, + public StepResult initialize(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler, EPerson currentUser) throws ParseException { if (currentUser != null) { this.setEpersonIdentifier(currentUser.getID()); } this.setHandler(dSpaceRunnableHandler); - this.parse(args); + + // parse the command line in a first step for the help options + // --> no other option is required + StepResult result = this.parseForHelp(args); + switch (result) { + case Exit: + // arguments of the command line matches the help options, handle this + handleHelpCommandLine(); + break; + + case Continue: + // arguments of the command line matches NOT the help options, parse the args for the normal options + result = this.parse(args); + break; + } + + return result; } - /** + + /** This method handle the help command line. In this easy implementation only the help is printed. + * For more complexity override this method. + */ + private void handleHelpCommandLine() { + printHelp(); + } + + + /** * This method will take the primitive array of String objects that represent the parameters given to the String * and it'll parse these into a CommandLine object that can be used by the script to retrieve the data * @param args The primitive array of Strings representing the parameters * @throws ParseException If something goes wrong */ - private void parse(String[] args) throws ParseException { + private StepResult parse(String[] args) throws ParseException { commandLine = new DefaultParser().parse(getScriptConfiguration().getOptions(), args); setup(); + return StepResult.Continue; } + + private StepResult parseForHelp(String[] args) throws ParseException { + helpCommandLine = new DefaultParser().parse(getScriptConfiguration().getHelpOptions(), args); + if (helpCommandLine.getOptions() != null && helpCommandLine.getOptions().length > 0) { + return StepResult.Exit; + } + + return StepResult.Continue; + } /** * This method has to be included in every script and handles the setup of the script by parsing the CommandLine @@ -158,4 +200,9 @@ public UUID getEpersonIdentifier() { public void setEpersonIdentifier(UUID epersonIdentifier) { this.epersonIdentifier = epersonIdentifier; } + + public enum StepResult { + Continue, + Exit; + } } diff --git a/dspace-api/src/main/java/org/dspace/scripts/configuration/ScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/scripts/configuration/ScriptConfiguration.java index 642409a924f7..62f30f99f65a 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/configuration/ScriptConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/scripts/configuration/ScriptConfiguration.java @@ -10,6 +10,7 @@ import java.sql.SQLException; import java.util.List; +import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.dspace.authorize.service.AuthorizeService; import org.dspace.core.Context; @@ -104,6 +105,20 @@ public boolean isAllowedToExecute(Context context, List Date: Mon, 7 Aug 2023 11:27:08 +0200 Subject: [PATCH 28/37] fix stylecheck --- .../dspace/app/launcher/ScriptLauncher.java | 10 ++- .../org/dspace/scripts/DSpaceRunnable.java | 70 ++++++++++--------- .../configuration/ScriptConfiguration.java | 11 ++- .../dspace/app/bulkedit/MetadataExportIT.java | 18 ++--- .../dspace/app/bulkedit/MetadataImportIT.java | 6 +- .../app/csv/CSVMetadataImportReferenceIT.java | 7 +- .../java/org/dspace/curate/CurationIT.java | 12 ++-- 7 files changed, 67 insertions(+), 67 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java index e6df016613b9..bcb61a48ee76 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java @@ -147,15 +147,13 @@ private static int executeScript(String[] args, DSpaceRunnableHandler dSpaceRunn DSpaceRunnable script) { try { StepResult result = script.initialize(args, dSpaceRunnableHandler, null); - if (StepResult.Continue.equals(result)) { - // only run the script, if the normal initialize is successful - script.run(); + // only run the script, if the normal initialize is successful + script.run(); } else { - // otherwise - for example the script is started with the help argument + // otherwise - for example the script is started with the help argument } - - return 0; + return 0; } catch (ParseException e) { script.printHelp(); e.printStackTrace(); diff --git a/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java b/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java index 4f64f6973179..7fb8567f8cd1 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java +++ b/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java @@ -35,7 +35,7 @@ public abstract class DSpaceRunnable implements R * The CommandLine object for the script that'll hold the information */ protected CommandLine commandLine; - + /** * The minimal CommandLine object for the script that'll hold help information */ @@ -69,8 +69,8 @@ private void setHandler(DSpaceRunnableHandler dSpaceRunnableHandler) { * @param args The arguments given to the script * @param dSpaceRunnableHandler The DSpaceRunnableHandler object that defines from where the script was ran * @param currentUser - * @return the result of this step; StepResult.Continue: continue the normal process, initialize is successful; - * otherwise exit the process (the help or version is shown) + * @return the result of this step; StepResult.Continue: continue the normal process, + * initialize is successful; otherwise exit the process (the help or version is shown) * @throws ParseException If something goes wrong */ public StepResult initialize(String[] args, DSpaceRunnableHandler dSpaceRunnableHandler, @@ -79,35 +79,38 @@ public StepResult initialize(String[] args, DSpaceRunnableHandler dSpaceRunnable this.setEpersonIdentifier(currentUser.getID()); } this.setHandler(dSpaceRunnableHandler); - - // parse the command line in a first step for the help options + + // parse the command line in a first step for the help options // --> no other option is required StepResult result = this.parseForHelp(args); switch (result) { - case Exit: - // arguments of the command line matches the help options, handle this - handleHelpCommandLine(); - break; - - case Continue: - // arguments of the command line matches NOT the help options, parse the args for the normal options - result = this.parse(args); - break; - } - + case Exit: + // arguments of the command line matches the help options, handle this + handleHelpCommandLine(); + break; + + case Continue: + // arguments of the command line matches NOT the help options, parse the args for the normal options + result = this.parse(args); + break; + default: + break; + } + return result; } - /** This method handle the help command line. In this easy implementation only the help is printed. - * For more complexity override this method. - */ - private void handleHelpCommandLine() { - printHelp(); - } + /** + * This method handle the help command line. In this easy implementation only the help is printed. For more + * complexity override this method. + */ + private void handleHelpCommandLine() { + printHelp(); + } - /** + /** * This method will take the primitive array of String objects that represent the parameters given to the String * and it'll parse these into a CommandLine object that can be used by the script to retrieve the data * @param args The primitive array of Strings representing the parameters @@ -118,15 +121,15 @@ private StepResult parse(String[] args) throws ParseException { setup(); return StepResult.Continue; } - + private StepResult parseForHelp(String[] args) throws ParseException { - helpCommandLine = new DefaultParser().parse(getScriptConfiguration().getHelpOptions(), args); - if (helpCommandLine.getOptions() != null && helpCommandLine.getOptions().length > 0) { - return StepResult.Exit; - } - - return StepResult.Continue; - } + helpCommandLine = new DefaultParser().parse(getScriptConfiguration().getHelpOptions(), args); + if (helpCommandLine.getOptions() != null && helpCommandLine.getOptions().length > 0) { + return StepResult.Exit; + } + + return StepResult.Continue; + } /** * This method has to be included in every script and handles the setup of the script by parsing the CommandLine @@ -200,9 +203,8 @@ public UUID getEpersonIdentifier() { public void setEpersonIdentifier(UUID epersonIdentifier) { this.epersonIdentifier = epersonIdentifier; } - + public enum StepResult { - Continue, - Exit; + Continue, Exit; } } diff --git a/dspace-api/src/main/java/org/dspace/scripts/configuration/ScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/scripts/configuration/ScriptConfiguration.java index 62f30f99f65a..bbedab04e278 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/configuration/ScriptConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/scripts/configuration/ScriptConfiguration.java @@ -105,17 +105,16 @@ public boolean isAllowedToExecute(Context context, List Date: Tue, 8 Aug 2023 09:36:16 +0200 Subject: [PATCH 29/37] ingore unrecognized arguments on help --- dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java b/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java index 7fb8567f8cd1..5e16fea5aecd 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java +++ b/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java @@ -123,7 +123,7 @@ private StepResult parse(String[] args) throws ParseException { } private StepResult parseForHelp(String[] args) throws ParseException { - helpCommandLine = new DefaultParser().parse(getScriptConfiguration().getHelpOptions(), args); + helpCommandLine = new DefaultParser().parse(getScriptConfiguration().getHelpOptions(), args, true); if (helpCommandLine.getOptions() != null && helpCommandLine.getOptions().length > 0) { return StepResult.Exit; } From 1f3ad993cc4d10694112227245be3de1ec7b3762 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 8 Aug 2023 16:43:12 -0500 Subject: [PATCH 30/37] Remove useless log.info --- .../src/main/java/org/dspace/content/BundleServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/content/BundleServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/BundleServiceImpl.java index 20c43e4bfc73..546d48d4306b 100644 --- a/dspace-api/src/main/java/org/dspace/content/BundleServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/BundleServiceImpl.java @@ -194,7 +194,6 @@ public void addBitstream(Context context, Bundle bundle, Bitstream bitstream) List defaultBitstreamReadGroups = authorizeService.getAuthorizedGroups(context, owningCollection, Constants.DEFAULT_BITSTREAM_READ); - log.info(defaultBitstreamReadGroups.size()); // If this collection is configured with a DEFAULT_BITSTREAM_READ group, overwrite the READ policy // inherited from the bundle with this policy. if (!defaultBitstreamReadGroups.isEmpty()) { From 08c650921d7ce5210906db846ff29a053c2155a7 Mon Sep 17 00:00:00 2001 From: aroman-arvo Date: Fri, 11 Aug 2023 08:47:31 +0200 Subject: [PATCH 31/37] 3331 - remove the --optimize feature of 'dspace stats-util' --- .../dspace/statistics/SolrLoggerServiceImpl.java | 16 ---------------- .../statistics/service/SolrLoggerService.java | 6 ------ .../dspace/statistics/util/StatisticsClient.java | 3 --- 3 files changed, 25 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java b/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java index 19c79af34dcc..97585f5a47cb 100644 --- a/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/statistics/SolrLoggerServiceImpl.java @@ -1203,22 +1203,6 @@ public String getIgnoreSpiderIPs() { } - @Override - public void optimizeSOLR() { - try { - long start = System.currentTimeMillis(); - System.out.println("SOLR Optimize -- Process Started:" + start); - solr.optimize(); - long finish = System.currentTimeMillis(); - System.out.println("SOLR Optimize -- Process Finished:" + finish); - System.out.println("SOLR Optimize -- Total time taken:" + (finish - start) + " (ms)."); - } catch (SolrServerException sse) { - System.err.println(sse.getMessage()); - } catch (IOException ioe) { - System.err.println(ioe.getMessage()); - } - } - @Override public void shardSolrIndex() throws IOException, SolrServerException { if (!(solr instanceof HttpSolrClient)) { diff --git a/dspace-api/src/main/java/org/dspace/statistics/service/SolrLoggerService.java b/dspace-api/src/main/java/org/dspace/statistics/service/SolrLoggerService.java index 3728318625e3..61b2bb6013de 100644 --- a/dspace-api/src/main/java/org/dspace/statistics/service/SolrLoggerService.java +++ b/dspace-api/src/main/java/org/dspace/statistics/service/SolrLoggerService.java @@ -266,12 +266,6 @@ public QueryResponse query(String query, String filterQuery, */ public String getIgnoreSpiderIPs(); - /** - * Maintenance to keep a SOLR index efficient. - * Note: This might take a long time. - */ - public void optimizeSOLR(); - public void shardSolrIndex() throws IOException, SolrServerException; public void reindexBitstreamHits(boolean removeDeletedBitstreams) throws Exception; diff --git a/dspace-api/src/main/java/org/dspace/statistics/util/StatisticsClient.java b/dspace-api/src/main/java/org/dspace/statistics/util/StatisticsClient.java index e45ce163ed77..319fe437d648 100644 --- a/dspace-api/src/main/java/org/dspace/statistics/util/StatisticsClient.java +++ b/dspace-api/src/main/java/org/dspace/statistics/util/StatisticsClient.java @@ -67,7 +67,6 @@ public static void main(String[] args) throws Exception { options.addOption("m", "mark-spiders", false, "Update isBot Flag in Solr"); options.addOption("f", "delete-spiders-by-flag", false, "Delete Spiders in Solr By isBot Flag"); options.addOption("i", "delete-spiders-by-ip", false, "Delete Spiders in Solr By IP Address"); - options.addOption("o", "optimize", false, "Run maintenance on the SOLR index"); options.addOption("b", "reindex-bitstreams", false, "Reindex the bitstreams to ensure we have the bundle name"); options.addOption("e", "export", false, "Export SOLR view statistics data to usage-statistics-intermediate-format"); @@ -93,8 +92,6 @@ public static void main(String[] args) throws Exception { solrLoggerService.deleteRobotsByIsBotFlag(); } else if (line.hasOption('i')) { solrLoggerService.deleteRobotsByIP(); - } else if (line.hasOption('o')) { - solrLoggerService.optimizeSOLR(); } else if (line.hasOption('b')) { solrLoggerService.reindexBitstreamHits(line.hasOption('r')); } else if (line.hasOption('e')) { From ca8abddff1230e581501b482623966e64016d609 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Mon, 21 Aug 2023 23:35:23 +0200 Subject: [PATCH 32/37] README.md: Fix typo --- dspace-server-webapp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/README.md b/dspace-server-webapp/README.md index 8d3853e8ccc7..d418124ea171 100644 --- a/dspace-server-webapp/README.md +++ b/dspace-server-webapp/README.md @@ -10,7 +10,7 @@ This webapp uses the following technologies: We don't use Spring Data REST as we haven't a spring data layer and we want to provide clear separation between the persistence representation and the REST representation ## How to contribute -Check the infomation available on the DSpace Official Wiki page for the [DSpace 7 Working Group](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Working+Group) +Check the information available on the DSpace Official Wiki page for the [DSpace 7 Working Group](https://wiki.duraspace.org/display/DSPACE/DSpace+7+UI+Working+Group) [DSpace 7 REST: Coding DSpace Objects](https://wiki.duraspace.org/display/DSPACE/DSpace+7+REST%3A+Coding+DSpace+Objects) From 940183411ea6ea87aa5de9193794c553178637d4 Mon Sep 17 00:00:00 2001 From: Hrafn Malmquist Date: Tue, 22 Aug 2023 21:24:24 +0100 Subject: [PATCH 33/37] Bump up versions of buildnumber-maven-plugin & build-helper-maven-plugin. add configuration for SCM failure (#9016) --- Dockerfile | 2 +- dspace-api/pom.xml | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 664cba89faea..dd633def28d9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,7 +51,7 @@ RUN ant init_installation update_configs update_code update_webapps FROM tomcat:9-jdk${JDK_VERSION} # NOTE: DSPACE_INSTALL must align with the "dspace.dir" default configuration. ENV DSPACE_INSTALL=/dspace -# Copy the /dspace directory from 'ant_build' containger to /dspace in this container +# Copy the /dspace directory from 'ant_build' container to /dspace in this container COPY --from=ant_build /dspace $DSPACE_INSTALL # Expose Tomcat port and AJP port EXPOSE 8080 8009 diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index ee8c21cb64bd..45aee2227ac9 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -102,7 +102,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.0.0 + 3.4.0 validate @@ -116,7 +116,10 @@ org.codehaus.mojo buildnumber-maven-plugin - 1.4 + 3.2.0 + + UNKNOWN_REVISION + validate From 86285d78aa0844b9811dcebdefa897ceeb944226 Mon Sep 17 00:00:00 2001 From: Christian Bethge Date: Wed, 23 Aug 2023 10:33:51 +0200 Subject: [PATCH 34/37] add DSpaceSkipUnknownArgumentsParser as parser to ignore/skip unknown arguments in cli by help, fix not necessary ParseException in help --- .../cli/DSpaceSkipUnknownArgumentsParser.java | 77 +++++++++++++++++++ .../org/dspace/scripts/DSpaceRunnable.java | 3 +- 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 dspace-api/src/main/java/org/dspace/cli/DSpaceSkipUnknownArgumentsParser.java diff --git a/dspace-api/src/main/java/org/dspace/cli/DSpaceSkipUnknownArgumentsParser.java b/dspace-api/src/main/java/org/dspace/cli/DSpaceSkipUnknownArgumentsParser.java new file mode 100644 index 000000000000..afd74a588d17 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/cli/DSpaceSkipUnknownArgumentsParser.java @@ -0,0 +1,77 @@ +/** + * 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.cli; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +/** + * Extended version of the DefaultParser. This parser skip/ignore unknown arguments. + */ +public class DSpaceSkipUnknownArgumentsParser extends DefaultParser { + + + @Override + public CommandLine parse(Options options, String[] arguments) throws ParseException { + return super.parse(options, getOnlyKnownArguments(options, arguments)); + } + + @Override + public CommandLine parse(Options options, String[] arguments, Properties properties) throws ParseException { + return super.parse(options, getOnlyKnownArguments(options, arguments), properties); + } + + /** + * Parse the arguments according to the specified options and properties. + * @param options the specified Options + * @param arguments the command line arguments + * @param stopAtNonOption can be ignored - an unrecognized argument is ignored, an unrecognized argument doesn't + * stop the parsing and doesn't trigger a ParseException + * + * @return the list of atomic option and value tokens + * @throws ParseException if there are any problems encountered while parsing the command line tokens. + */ + @Override + public CommandLine parse(Options options, String[] arguments, boolean stopAtNonOption) throws ParseException { + return super.parse(options, getOnlyKnownArguments(options, arguments), stopAtNonOption); + } + + /** + * Parse the arguments according to the specified options and properties. + * @param options the specified Options + * @param arguments the command line arguments + * @param properties command line option name-value pairs + * @param stopAtNonOption can be ignored - an unrecognized argument is ignored, an unrecognized argument doesn't + * stop the parsing and doesn't trigger a ParseException + * + * @return the list of atomic option and value tokens + * @throws ParseException if there are any problems encountered while parsing the command line tokens. + */ + @Override + public CommandLine parse(Options options, String[] arguments, Properties properties, boolean stopAtNonOption) + throws ParseException { + return super.parse(options, getOnlyKnownArguments(options, arguments), properties, stopAtNonOption); + } + + + private String[] getOnlyKnownArguments(Options options, String[] arguments) { + List knownArguments = new ArrayList<>(); + for (String arg : arguments) { + if (options.hasOption(arg)) { + knownArguments.add(arg); + } + } + return knownArguments.toArray(new String[0]); + } +} diff --git a/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java b/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java index 5e16fea5aecd..2ea0a52d6e34 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java +++ b/dspace-api/src/main/java/org/dspace/scripts/DSpaceRunnable.java @@ -18,6 +18,7 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.lang3.StringUtils; +import org.dspace.cli.DSpaceSkipUnknownArgumentsParser; import org.dspace.eperson.EPerson; import org.dspace.scripts.configuration.ScriptConfiguration; import org.dspace.scripts.handler.DSpaceRunnableHandler; @@ -123,7 +124,7 @@ private StepResult parse(String[] args) throws ParseException { } private StepResult parseForHelp(String[] args) throws ParseException { - helpCommandLine = new DefaultParser().parse(getScriptConfiguration().getHelpOptions(), args, true); + helpCommandLine = new DSpaceSkipUnknownArgumentsParser().parse(getScriptConfiguration().getHelpOptions(), args); if (helpCommandLine.getOptions() != null && helpCommandLine.getOptions().length > 0) { return StepResult.Exit; } From 064e2caa37dfa283c3c08dee0e7321e36073bfa2 Mon Sep 17 00:00:00 2001 From: Christian Bethge Date: Wed, 23 Aug 2023 10:41:44 +0200 Subject: [PATCH 35/37] remove not necessary else --- .../main/java/org/dspace/app/launcher/ScriptLauncher.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java index bcb61a48ee76..89a416bfa883 100644 --- a/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java +++ b/dspace-api/src/main/java/org/dspace/app/launcher/ScriptLauncher.java @@ -147,11 +147,11 @@ private static int executeScript(String[] args, DSpaceRunnableHandler dSpaceRunn DSpaceRunnable script) { try { StepResult result = script.initialize(args, dSpaceRunnableHandler, null); + // check the StepResult, only run the script if the result is Continue; + // otherwise - for example the script is started with the help as argument, nothing is to do if (StepResult.Continue.equals(result)) { - // only run the script, if the normal initialize is successful + // runs the script, the normal initialization is successful script.run(); - } else { - // otherwise - for example the script is started with the help argument } return 0; } catch (ParseException e) { From c23bc8a33867759919fd8fce0c28118a8630427e Mon Sep 17 00:00:00 2001 From: Martin Walk Date: Thu, 3 Aug 2023 13:39:43 +0200 Subject: [PATCH 36/37] Fix #8963: Remove deletion constraint from Groomer (cherry picked from commit e07763b021c009e421b97dc5b6404c284c9de168) --- .../main/java/org/dspace/eperson/Groomer.java | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/eperson/Groomer.java b/dspace-api/src/main/java/org/dspace/eperson/Groomer.java index 2a828cdc12b4..5485bb1d0ca9 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/Groomer.java +++ b/dspace-api/src/main/java/org/dspace/eperson/Groomer.java @@ -141,20 +141,10 @@ private static void aging(CommandLine command) throws SQLException { System.out.println(); if (delete) { - List whyNot = ePersonService.getDeleteConstraints(myContext, account); - if (!whyNot.isEmpty()) { - System.out.print("\tCannot be deleted; referenced in"); - for (String table : whyNot) { - System.out.print(' '); - System.out.print(table); - } - System.out.println(); - } else { - try { - ePersonService.delete(myContext, account); - } catch (AuthorizeException | IOException ex) { - System.err.println(ex.getMessage()); - } + try { + ePersonService.delete(myContext, account); + } catch (AuthorizeException | IOException ex) { + System.err.println(ex.getMessage()); } } } From b1d3471995ce7687b4ca256b90d6c1487e9719dd Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 23 Aug 2023 16:51:26 -0500 Subject: [PATCH 37/37] Enable new skip merge commit feature --- .github/workflows/port_merged_pull_request.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/port_merged_pull_request.yml b/.github/workflows/port_merged_pull_request.yml index 50faf3f88679..109835d14d3c 100644 --- a/.github/workflows/port_merged_pull_request.yml +++ b/.github/workflows/port_merged_pull_request.yml @@ -39,6 +39,8 @@ jobs: # Copy all labels from original PR to (newly created) port PR # NOTE: The labels matching 'label_pattern' are automatically excluded copy_labels_pattern: '.*' + # Skip any merge commits in the ported PR. This means only non-merge commits are cherry-picked to the new PR + merge_commits: 'skip' # Use a personal access token (PAT) to create PR as 'dspace-bot' user. # A PAT is required in order for the new PR to trigger its own actions (for CI checks) github_token: ${{ secrets.PR_PORT_TOKEN }} \ No newline at end of file