Skip to content

Commit

Permalink
ufal/be-collection2item-table-is-not-migrated (#439)
Browse files Browse the repository at this point in the history
* Created endpoint for importing item's mapped collections and created test for it

* Fixed checkstyle issues

* Fixed conflicts

* refactoring

* Refactoring according to request changes
  • Loading branch information
milanmajchrak authored Oct 3, 2023
1 parent a965335 commit aa6c260
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
package org.dspace.app.rest.repository;

import static org.dspace.app.rest.utils.ContextUtil.obtainContext;
import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID;
import static org.dspace.core.Constants.COLLECTION;

import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -20,17 +23,20 @@
import javax.servlet.http.HttpServletRequest;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.converter.MetadataConverter;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.model.WorkspaceItemRest;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.Utils;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Collection;
import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.content.MetadataValue;
import org.dspace.content.WorkspaceItem;
Expand All @@ -51,6 +57,8 @@
import org.dspace.workflow.WorkflowException;
import org.dspace.xmlworkflow.service.XmlWorkflowService;
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
import org.json.simple.JSONArray;
import org.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -366,6 +374,79 @@ public ItemRest importItem(HttpServletRequest request) throws SQLException, Auth
return itemRest;
}

/**
* Endpoint for importing item's mapped collection.
* The mapping for requested endpoint, for example
* <pre>
* {@code
* https://<dspace.server.url>/api/clarin/import/item/{ITEM_UUID}/mappedCollections
* }
* </pre>
* @param request request
* @throws SQLException if database error
* @throws AuthorizeException if authorization error
*/
@PreAuthorize("hasAuthority('ADMIN')")
@RequestMapping(method = RequestMethod.POST, value = "/item" + REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID +
"/mappedCollections")
public void importItemCollections(@PathVariable UUID uuid, HttpServletRequest request) throws SQLException,
AuthorizeException {
Context context = ContextUtil.obtainContext(request);
if (Objects.isNull(context)) {
throw new RuntimeException("Context is null - cannot import item's mapped collections.");
}

// Load List of collection self links
List<String> requestAsStringList = new ArrayList<>();
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new InputStreamReader(request.getInputStream()));

if (!(obj instanceof JSONArray)) {
throw new UnprocessableEntityException("The request is not a JSON Array");
}

for (Object entity : (JSONArray) obj) {
String collectionSelfLink = entity.toString();
requestAsStringList.add(collectionSelfLink);
}
} catch (Exception e) {
throw new RuntimeException("Cannot import item's mapped collections because parsing of the request JSON" +
"throws this error: " + e.getMessage());
}

// Find Collections following its self link
List<DSpaceObject> listDsoFoundInRequest
= utils.constructDSpaceObjectList(context, requestAsStringList);

if (CollectionUtils.isEmpty(listDsoFoundInRequest)) {
throw new UnprocessableEntityException("Not a valid collection uuid.");
}

for (DSpaceObject dso : listDsoFoundInRequest) {

Item item = itemService.find(context, uuid);
if (dso != null && dso.getType() == COLLECTION && item != null) {
if (this.checkIfItemIsTemplate(item)) {
continue;
}

Collection collectionToMapTo = (Collection) dso;
if (this.checkIfOwningCollection(item, collectionToMapTo.getID())) {
continue;
}

collectionService.addItem(context, collectionToMapTo, item);
collectionService.update(context, collectionToMapTo);
itemService.update(context, item);
} else {
throw new UnprocessableEntityException("Not a valid collection or item uuid.");
}
}

context.commit();
}

/**
* Convert String input value to boolean.
* @param value input value
Expand All @@ -391,4 +472,18 @@ private Integer getIntegerFromString(String value) {
}
return output;
}
}

private boolean checkIfItemIsTemplate(Item item) {
return item.getTemplateItemOf() != null;
}

private boolean checkIfOwningCollection(Item item, UUID collectionID) {
if (Objects.isNull(item)) {
return false;
}
if (Objects.isNull(item.getOwningCollection())) {
return false;
}
return item.getOwningCollection().getID().equals(collectionID);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
Expand All @@ -33,6 +34,7 @@
import org.dspace.builder.WorkflowItemBuilder;
import org.dspace.builder.WorkspaceItemBuilder;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.Item;
import org.dspace.content.MetadataValue;
import org.dspace.content.WorkspaceItem;
Expand Down Expand Up @@ -470,4 +472,54 @@ public void testImportAuthorityAndConfidenceInMetadata() throws Exception {
assertEquals(dcRelationValue.getAuthority(), String.valueOf(AUTHORITY));
assertEquals(dcRelationValue.getConfidence(), CONFIDENCE);
}

@Test
public void importItemsMappedCollections() throws Exception {
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("Collection 3").build();

//2. Public item that is readable by Anonymous with different subjects
Item publicItem1 = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();

String startOfCollectionLink = "https://localhost:8080/spring-rest/api/core/collections/";
// It is owning collection
String col1SelfLink = startOfCollectionLink + col1.getID();
String col2SelfLink = startOfCollectionLink + col2.getID();
String col3SelfLink = startOfCollectionLink + col3.getID();
List<String> collectionSelfLinksList = new ArrayList<>();
collectionSelfLinksList.add(col1SelfLink);
collectionSelfLinksList.add(col2SelfLink);
collectionSelfLinksList.add(col3SelfLink);

ObjectMapper mapper = new ObjectMapper();
String token = getAuthToken(admin.getEmail(), password);

getClient(token).perform(post("/api/clarin/import/item/" +
publicItem1.getID() + "/mappedCollections")
.content(mapper.writeValueAsBytes(collectionSelfLinksList))
.contentType(org.springframework.http.MediaType.APPLICATION_JSON))
.andExpect(status().isOk());

Item updatedItem = itemService.find(context, publicItem1.getID());
assertEquals(updatedItem.getCollections().size(), 3);
assertTrue(updatedItem.getCollections().contains(col1));
assertTrue(updatedItem.getCollections().contains(col2));
assertTrue(updatedItem.getCollections().contains(col3));
}
}

0 comments on commit aa6c260

Please sign in to comment.