Skip to content

Commit da6b0ad

Browse files
milanmajchrakPaurikova2kosarkoKasinhouMatus Kasak
authored
New Release merge - 2025/July/10 (#1008)
* UFAL/DOI - Added type of resource to data cite (#975) * UFAL/The process output is not displayed because of S3 direct download (#971) * The S3 direct download is provided only for the files located in the ORIGINAL bundle * Use constant for the ORIGINAL string value * Check if type is html (#983) * check if type is html * added test for html mime type * used static string for text/html, added check * Ufal dtq sync062025 (#985) * we should identify as clarin-dspace Fix test (cherry picked from commit 6cdf2d1) * update email templates to use dspace.shortname dspace.name can be a long string not fit for Email subjects nor signatures (cherry picked from commit 98d60dd) * match v5 submission (cherry picked from commit 4a2b65f) * get rid of lr.help.phone Phone is now conditional in the templates. Use `mail.message.helpdesk.telephone` if you want it. The change in the *.java files is to preserve the params counts. The relevant templates are getting the phone directly from config (cherry picked from commit cba5695) * Add option to configure oai sample identifier some validators use this value, should be a real id in prod deployments (cherry picked from commit 912f13f) * NRP deposit license (cherry picked from commit ba23878) * Fix ufal#1219 Get rid of setting the jsse.enableSNIExtension property which causes issues with handle minting (cherry picked from commit 7d03173) * UFAL/Improve file preview generating (#972) * get name and size from metadata and header of file, avoid input stream using * remove temp file, checkstyle, do not load full file * add { } after if * added check for max preview file * used ZipFile and TarArchived for filepreview generating * added removed lines * used 7z for zip and tar files * removed 7z and used zip and tar entry * improved file previrew generating speed, used string builder, xml builder, authorization only if is required * checkstyle, return boolean from haspreview and previrews from getPreview, replaced return with continue * fix problem with hibernate session * fix .tar.gz generating * skip fully entry for tar * added indexes for speed up queries * added license header * named constant by upper case * inicialized fileInfo, refactorization of code based on copilot review --------- Co-authored-by: milanmajchrak <90026355+milanmajchrak@users.noreply.github.com> * Fix the file preview integration test (#989) * The hasPreview method has been changed, but the IT wasn't updated correctly * Use the correct checkbox for the input field - use repeatable (#991) * UFAL/EU Sponsor openaire id should not be required (#1001) * EU Sponsor openaire id should not be required * Not required also in the czech submission forms * Logging error message while emailing users (#1000) * Logging error message --------- Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk> Co-authored-by: milanmajchrak <milan.majchrak@dataquest.sk> * UFAL/Teaching and clariah submissions does not have clarin-license (#1005) * UFAL/Fix logging in LogoImportController (#1003) * fix logging * used formatter for msg * UFAL/Update the resource policy rights when changing submitter (#1002) * removed res policies for submitter and created newones when item is shared * avoid magic number, use constant * set submitter in existing res policies * removed not used shared link * UFAL/Added date to title when creating new version (#984) * added date to versioned item title * used more modern approach for getting current time * renamed test * used var for reusing * UFAL/Item handle info in email after download request (#1006) * Added item handle to email * Exception when item not found * Checked grammar * Handled multiple items found by bitstream * Using PID instead of handle --------- Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk> --------- Co-authored-by: Paurikova2 <107862249+Paurikova2@users.noreply.github.com> Co-authored-by: Ondřej Košarko <ko_ok@centrum.cz> Co-authored-by: Kasinhou <129340513+Kasinhou@users.noreply.github.com> Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk> Co-authored-by: jurinecko <95219754+jr-rk@users.noreply.github.com>
1 parent 4149d65 commit da6b0ad

16 files changed

Lines changed: 261 additions & 47 deletions

File tree

dspace-api/src/main/java/org/dspace/versioning/DefaultItemVersionProvider.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@
99

1010
import java.io.IOException;
1111
import java.sql.SQLException;
12+
import java.time.LocalDate;
13+
import java.time.format.DateTimeFormatter;
1214
import java.util.List;
1315

1416
import org.apache.logging.log4j.Logger;
1517
import org.dspace.authorize.AuthorizeException;
1618
import org.dspace.authorize.ResourcePolicy;
1719
import org.dspace.content.Item;
20+
import org.dspace.content.MetadataSchemaEnum;
1821
import org.dspace.content.Relationship;
1922
import org.dspace.content.WorkspaceItem;
2023
import org.dspace.content.service.RelationshipService;
@@ -36,6 +39,7 @@
3639
public class DefaultItemVersionProvider extends AbstractVersionProvider implements ItemVersionProvider {
3740

3841
Logger log = org.apache.logging.log4j.LogManager.getLogger(DefaultItemVersionProvider.class);
42+
private static final String UNTITLED = "Untitled"; // Default title for items without a name
3943

4044
@Autowired(required = true)
4145
protected WorkspaceItemService workspaceItemService;
@@ -128,6 +132,17 @@ public Item updateItemState(Context c, Item itemNew, Item previousItem) {
128132
// are added to the previous item in the VersionRestRepository.
129133
manageRelationMetadata(c, itemNew, previousItem);
130134

135+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
136+
String formattedDate = LocalDate.now().format(formatter);
137+
String itemName = itemNew.getName();
138+
if (itemName == null) {
139+
itemName = UNTITLED;
140+
}
141+
String titleWithDate = itemName + " (" + formattedDate + ")";
142+
// Set the item's title with the formatted date appended
143+
itemService.setMetadataSingleValue(c, itemNew, MetadataSchemaEnum.DC.getName(),
144+
"title", null, Item.ANY, titleWithDate);
145+
131146
itemService.update(c, itemNew);
132147
return itemNew;
133148
} catch (IOException | SQLException | AuthorizeException e) {

dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignOriginalSubmitterAction.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,9 @@ public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers r
8787
xmlWorkflowService.getMyDSpaceLink()
8888
);
8989
} catch (MessagingException e) {
90-
log.info(LogHelper.getHeader(c, "error emailing user(s) for claimed task",
91-
"step: " + getParent().getStep().getId() + " workflowitem: " + wfi.getID()));
90+
log.error(LogHelper.getHeader(c, "error emailing user(s) for claimed task",
91+
"step: " + getParent().getStep().getId() + " workflowitem: " +
92+
wfi.getID()) + ", because of this error " + e.getMessage());
9293
}
9394
}
9495
}

dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/ClaimAction.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers r
9696
xmlWorkflowService.getMyDSpaceLink()
9797
);
9898
} catch (MessagingException e) {
99-
log.info(LogHelper.getHeader(c, "error emailing user(s) for claimed task",
100-
"step: " + getParent().getStep().getId() + " workflowitem: " + wfi.getID()));
99+
log.error(LogHelper.getHeader(c, "error emailing user(s) for claimed task",
100+
"step: " + getParent().getStep().getId() + " workflowitem: " +
101+
wfi.getID()) + ", because of this error " + e.getMessage());
101102
}
102103
}
103104

dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import static org.junit.Assert.assertTrue;
2929

3030
import java.sql.SQLException;
31+
import java.time.LocalDate;
32+
import java.time.format.DateTimeFormatter;
3133
import java.util.ArrayList;
3234
import java.util.HashMap;
3335
import java.util.List;
@@ -83,6 +85,7 @@ public class VersioningWithRelationshipsIT extends AbstractIntegrationTestWithDa
8385
DSpaceServicesFactory.getInstance().getServiceManager().getServicesByType(SolrSearchCore.class).get(0);
8486
protected Community community;
8587
protected Collection collection;
88+
protected String formattedDate;
8689
protected EntityType publicationEntityType;
8790
protected EntityType personEntityType;
8891
protected EntityType projectEntityType;
@@ -192,6 +195,9 @@ public void setUp() throws Exception {
192195
.withCopyToLeft(false)
193196
.withCopyToRight(false)
194197
.build();
198+
199+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
200+
formattedDate = LocalDate.now().format(formatter);
195201
}
196202

197203
protected Relationship getRelationship(
@@ -2112,7 +2118,7 @@ public void test_placeRecalculationAfterDelete_complex() throws Exception {
21122118
//////////////////
21132119
// create items //
21142120
//////////////////
2115-
2121+
String person3itemDate = "person 3 (item) (" + formattedDate + ")";
21162122
// person 1.1
21172123
Item pe1_1 = ItemBuilder.createItem(context, collection)
21182124
.withTitle("person 1 (item)")
@@ -2394,7 +2400,7 @@ public void test_placeRecalculationAfterDelete_complex() throws Exception {
23942400
assertEquals(1, mdvs5.get(1).getPlace());
23952401

23962402
assertTrue(mdvs5.get(2) instanceof RelationshipMetadataValue);
2397-
assertEquals("person 3 (item)", mdvs5.get(2).getValue());
2403+
assertEquals(person3itemDate, mdvs5.get(2).getValue());
23982404
assertEquals(2, mdvs5.get(2).getPlace());
23992405

24002406
assertFalse(mdvs5.get(3) instanceof RelationshipMetadataValue);
@@ -2436,7 +2442,7 @@ public void test_placeRecalculationAfterDelete_complex() throws Exception {
24362442
assertEquals(1, mdvs6.get(1).getPlace());
24372443

24382444
assertTrue(mdvs6.get(2) instanceof RelationshipMetadataValue);
2439-
assertEquals("person 3 (item)", mdvs6.get(2).getValue());
2445+
assertEquals(person3itemDate, mdvs6.get(2).getValue());
24402446
assertEquals(2, mdvs6.get(2).getPlace());
24412447

24422448
////////////////////////////////////////////////
@@ -2509,7 +2515,7 @@ public void test_placeRecalculationAfterDelete_complex() throws Exception {
25092515
assertEquals(1, mdvs8.get(1).getPlace());
25102516

25112517
assertTrue(mdvs8.get(2) instanceof RelationshipMetadataValue);
2512-
assertEquals("person 3 (item)", mdvs8.get(2).getValue());
2518+
assertEquals(person3itemDate, mdvs8.get(2).getValue());
25132519
assertEquals(2, mdvs8.get(2).getPlace());
25142520

25152521
assertFalse(mdvs8.get(3) instanceof RelationshipMetadataValue);
@@ -2614,7 +2620,7 @@ public void test_placeRecalculationAfterDelete_complex() throws Exception {
26142620
assertEquals(1, mdvs10.get(1).getPlace());
26152621

26162622
assertTrue(mdvs10.get(2) instanceof RelationshipMetadataValue);
2617-
assertEquals("person 3 (item)", mdvs10.get(2).getValue());
2623+
assertEquals(person3itemDate, mdvs10.get(2).getValue());
26182624
assertEquals(2, mdvs10.get(2).getPlace());
26192625

26202626
assertFalse(mdvs10.get(3) instanceof RelationshipMetadataValue);
@@ -2657,7 +2663,7 @@ public void test_placeRecalculationAfterDelete_complex() throws Exception {
26572663
assertEquals(1, mdvs11.get(1).getPlace());
26582664

26592665
assertTrue(mdvs11.get(2) instanceof RelationshipMetadataValue);
2660-
assertEquals("person 3 (item)", mdvs11.get(2).getValue());
2666+
assertEquals(person3itemDate, mdvs11.get(2).getValue());
26612667
assertEquals(2, mdvs11.get(2).getPlace());
26622668

26632669
////////////////////////////////////////
@@ -2823,7 +2829,7 @@ public void test_placeRecalculationAfterDelete_complex() throws Exception {
28232829
assertEquals(1, mdvs15.get(1).getPlace());
28242830

28252831
assertTrue(mdvs15.get(2) instanceof RelationshipMetadataValue);
2826-
assertEquals("person 3 (item)", mdvs15.get(2).getValue());
2832+
assertEquals(person3itemDate, mdvs15.get(2).getValue());
28272833
assertEquals(2, mdvs15.get(2).getPlace());
28282834

28292835
assertFalse(mdvs15.get(3) instanceof RelationshipMetadataValue);
@@ -2866,7 +2872,7 @@ public void test_placeRecalculationAfterDelete_complex() throws Exception {
28662872
assertEquals(1, mdvs16.get(1).getPlace());
28672873

28682874
assertTrue(mdvs16.get(2) instanceof RelationshipMetadataValue);
2869-
assertEquals("person 3 (item)", mdvs16.get(2).getValue());
2875+
assertEquals(person3itemDate, mdvs16.get(2).getValue());
28702876
assertEquals(2, mdvs16.get(2).getPlace());
28712877

28722878
////////////////////////////////////////

dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinLogoImportController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ public CollectionRest addCollectionLogo(HttpServletRequest request) throws SQLEx
160160
collectionService.addLogo(context, collection, newLogo);
161161
collectionService.update(context, collection);
162162
bitstreamService.update(context, newLogo);
163-
log.error("Logo with id: + " + newLogo.getID() + " was successfully added to collection " +
164-
"with id: " + collection.getID());
163+
log.info("Logo with id: {} was successfully added to collection with id: {}",
164+
newLogo.getID(), collection.getID());
165165

166166
CollectionRest collectionRest = converter.toRest(collection, utils.obtainProjection());
167167
context.commit();

dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinUserMetadataRestController.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.dspace.content.clarin.ClarinUserRegistration;
4848
import org.dspace.content.service.BitstreamService;
4949
import org.dspace.content.service.ItemService;
50+
import org.dspace.content.service.clarin.ClarinItemService;
5051
import org.dspace.content.service.clarin.ClarinLicenseResourceMappingService;
5152
import org.dspace.content.service.clarin.ClarinLicenseResourceUserAllowanceService;
5253
import org.dspace.content.service.clarin.ClarinUserMetadataService;
@@ -86,6 +87,8 @@ public class ClarinUserMetadataRestController {
8687

8788
@Autowired
8889
ItemService itemService;
90+
@Autowired
91+
ClarinItemService clarinItemService;
8992

9093
@Autowired
9194
ConfigurationService configurationService;
@@ -172,7 +175,7 @@ public ResponseEntity manageUserMetadataForZIP(@RequestParam("itemUUID") UUID it
172175
try {
173176
String email = getEmailFromUserMetadata(clarinUserMetadataRestList);
174177
this.sendEmailWithDownloadLink(context, item, clarinLicense,
175-
email, downloadToken, MailType.ALLZIP, clarinUserMetadataRestList);
178+
email, downloadToken, MailType.ALLZIP, clarinUserMetadataRestList, item.getHandle());
176179
} catch (MessagingException e) {
177180
log.error("Cannot send the download email because: " + e.getMessage());
178181
throw new RuntimeException("Cannot send the download email because: " + e.getMessage());
@@ -252,8 +255,16 @@ public ResponseEntity manageUserMetadata(@RequestParam("bitstreamUUID") UUID bit
252255
// If yes - send token to e-mail
253256
try {
254257
String email = getEmailFromUserMetadata(clarinUserMetadataRestList);
258+
List<Item> items = clarinItemService.findByBitstreamUUID(context, bitstreamUUID);
259+
if (CollectionUtils.isEmpty(items)) {
260+
throw new NotFoundException("No items found for the given bitstream UUID: " + bitstreamUUID);
261+
} else if (items.size() > 1) {
262+
// This situation is not expected. A bitstream should be linked to only one item.
263+
log.error("Multiple items ({}) found for bitstream UUID: {}. Expected only one.",
264+
items.size(), bitstreamUUID);
265+
}
255266
this.sendEmailWithDownloadLink(context, bitstream, clarinLicense,
256-
email, downloadToken, MailType.BITSTREAM, clarinUserMetadataRestList);
267+
email, downloadToken, MailType.BITSTREAM, clarinUserMetadataRestList, items.get(0).getHandle());
257268
} catch (MessagingException e) {
258269
log.error("Cannot send the download email because: " + e.getMessage());
259270
throw new RuntimeException("Cannot send the download email because: " + e.getMessage());
@@ -271,7 +282,8 @@ private void sendEmailWithDownloadLink(Context context, DSpaceObject dso,
271282
String email,
272283
String downloadToken,
273284
MailType mailType,
274-
List<ClarinUserMetadataRest> clarinUserMetadataRestList)
285+
List<ClarinUserMetadataRest> clarinUserMetadataRestList,
286+
String itemHandle)
275287
throws IOException, SQLException, MessagingException {
276288
if (StringUtils.isBlank(email)) {
277289
log.error("Cannot send email with download link because the email is empty.");
@@ -320,7 +332,8 @@ private void sendEmailWithDownloadLink(Context context, DSpaceObject dso,
320332
}
321333
// If previous mail fails with exception, this block never executes = admin is NOT
322334
// notified, if the mail is not really sent (if it fails HERE, not later, e.g. due to mail server issue).
323-
sendAdminNotificationEmail(context, downloadLink, dso, clarinLicense, mailType, clarinUserMetadataRestList);
335+
sendAdminNotificationEmail(context, downloadLink, dso, clarinLicense,
336+
mailType, clarinUserMetadataRestList, itemHandle);
324337

325338
}
326339

@@ -347,7 +360,8 @@ private List<String> getCCEmails(String ccAdmin, ClarinLicense clarinLicense) {
347360

348361
private void addAdminEmailArguments(Email mail, MailType mailType, DSpaceObject dso, String downloadLink,
349362
ClarinLicense clarinLicense, Context context,
350-
List<ClarinUserMetadataRest> extraMetadata) {
363+
List<ClarinUserMetadataRest> extraMetadata,
364+
String itemHandle) {
351365
if (mailType == MailType.ALLZIP) {
352366
mail.addArgument("all files requested");
353367
} else if (mailType == MailType.BITSTREAM) {
@@ -372,14 +386,16 @@ private void addAdminEmailArguments(Email mail, MailType mailType, DSpaceObject
372386
exdata.append(data.getMetadataKey()).append(": ").append(data.getMetadataValue()).append(", ");
373387
}
374388
mail.addArgument(exdata.toString());
389+
mail.addArgument(itemHandle);
375390
}
376391

377392
private void sendAdminNotificationEmail(Context context,
378393
String downloadLink,
379394
DSpaceObject dso,
380395
ClarinLicense clarinLicense,
381396
MailType mailType,
382-
List<ClarinUserMetadataRest> extraMetadata)
397+
List<ClarinUserMetadataRest> extraMetadata,
398+
String itemHandle)
383399
throws MessagingException, IOException {
384400
try {
385401
Locale locale = context.getCurrentLocale();
@@ -391,7 +407,8 @@ private void sendAdminNotificationEmail(Context context,
391407
for (String cc : ccEmails) {
392408
email2Admin.addRecipient(cc);
393409
}
394-
addAdminEmailArguments(email2Admin, mailType, dso, downloadLink, clarinLicense, context, extraMetadata);
410+
addAdminEmailArguments(email2Admin, mailType, dso, downloadLink,
411+
clarinLicense, context, extraMetadata, itemHandle);
395412

396413
}
397414
email2Admin.send();

dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionController.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,19 @@
2424
import org.dspace.app.rest.model.WorkspaceItemRest;
2525
import org.dspace.app.rest.utils.Utils;
2626
import org.dspace.authorize.AuthorizeException;
27+
import org.dspace.authorize.ResourcePolicy;
2728
import org.dspace.authorize.service.AuthorizeService;
29+
import org.dspace.authorize.service.ResourcePolicyService;
30+
import org.dspace.content.Collection;
2831
import org.dspace.content.WorkspaceItem;
2932
import org.dspace.content.service.WorkspaceItemService;
3033
import org.dspace.core.Constants;
3134
import org.dspace.core.Context;
3235
import org.dspace.core.Email;
3336
import org.dspace.core.I18nUtil;
3437
import org.dspace.eperson.EPerson;
38+
import org.dspace.eperson.Group;
39+
import org.dspace.eperson.service.GroupService;
3540
import org.dspace.services.ConfigurationService;
3641
import org.dspace.web.ContextUtil;
3742
import org.springframework.beans.factory.annotation.Autowired;
@@ -68,6 +73,12 @@ public class SubmissionController {
6873
@Autowired
6974
AuthorizeService authorizeService;
7075

76+
@Autowired
77+
GroupService groupService;
78+
79+
@Autowired
80+
ResourcePolicyService resourcePolicyService;
81+
7182
@Lazy
7283
@Autowired
7384
protected ConverterService converter;
@@ -145,12 +156,6 @@ public WorkspaceItemRest setOwner(@RequestParam(name = "shareToken") String shar
145156
// Check the wsi does exist
146157
validateWorkspaceItem(wsi, null, shareToken);
147158

148-
if (!authorizeService.authorizeActionBoolean(context, wsi.getItem(), Constants.READ)) {
149-
String errorMessage = "The current user does not have rights to view the WorkflowItem";
150-
log.error(errorMessage);
151-
throw new AccessDeniedException(errorMessage);
152-
}
153-
154159
// Set the owner of the workspace item to the current user
155160
EPerson currentUser = context.getCurrentUser();
156161
// If the current user is null, throw an exception
@@ -160,6 +165,25 @@ public WorkspaceItemRest setOwner(@RequestParam(name = "shareToken") String shar
160165
throw new DSpaceBadRequestException(errorMessage);
161166
}
162167

168+
Collection collection = wsi.getCollection();
169+
Group submittersGroup = collection.getSubmitters();
170+
boolean isSubmitterGroupMember = submittersGroup != null &&
171+
groupService.isMember(context, currentUser, submittersGroup);
172+
boolean canRead = authorizeService.authorizeActionBoolean(context, wsi.getItem(), Constants.READ);
173+
if (!canRead && !isSubmitterGroupMember) {
174+
String errorMessage = "The current user does not have rights to view or claim the WorkspaceItem";
175+
log.error(errorMessage);
176+
throw new AccessDeniedException(errorMessage);
177+
}
178+
179+
List<ResourcePolicy> resourcePolicies = resourcePolicyService.find(context,
180+
wsi.getItem(), ResourcePolicy.TYPE_SUBMISSION);
181+
// Set submitter
182+
for (ResourcePolicy resourcePolicy: resourcePolicies) {
183+
resourcePolicy.setEPerson(currentUser);
184+
resourcePolicyService.update(context, resourcePolicy);
185+
}
186+
163187
wsi.getItem().setSubmitter(currentUser);
164188
workspaceItemService.update(context, wsi);
165189
WorkspaceItemRest wsiRest = converter.toRest(wsi, utils.obtainProjection());

0 commit comments

Comments
 (0)