Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import static org.folio.processing.mapping.defaultmapper.processor.Processor.LDR_TAG;
import static org.folio.rest.jaxrs.model.MappingDetail.MarcMappingOption.MODIFY;
import static org.folio.rest.jaxrs.model.MarcMappingDetail.Action.DELETE;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.vertx.core.json.Json;
Expand Down Expand Up @@ -131,6 +132,10 @@ public void processUpdateMappingOption(List<MarcMappingDetail> marcMappingRules)

var notUpdatedDataFields = newLinkedList(incomingMarcRecord.getDataFields());
for (MarcMappingDetail detail : marcMappingRules) {
if (detail.getAction() == DELETE) {
processDeleteAction(detail, true);
continue;
}
String fieldTag = detail.getField().getField();
if (Verifier.isControlField(fieldTag)) {
incomingMarcRecord.getControlFields().stream()
Expand Down Expand Up @@ -451,25 +456,32 @@ private boolean isNumericalSortableField(VariableField field) {
}

private void processDeleteAction(MarcMappingDetail detail) {
processDeleteAction(detail, false);
}

private void processDeleteAction(MarcMappingDetail detail, boolean applyProtection) {
String fieldTag = detail.getField().getField();
char ind1 =
isNotEmpty(detail.getField().getIndicator1()) ? detail.getField().getIndicator1().charAt(0) : BLANK_SUBFIELD_CODE;
char ind2 =
isNotEmpty(detail.getField().getIndicator2()) ? detail.getField().getIndicator2().charAt(0) : BLANK_SUBFIELD_CODE;

if (Verifier.isControlField(fieldTag)) {
for (VariableField field : marcRecordToChange.getVariableFields(fieldTag)) {
marcRecordToChange.removeVariableField(field);
}
marcRecordToChange.getVariableFields(fieldTag).stream()
.filter(field -> !applyProtection || isNotProtected((ControlField) field))
.toList()
.forEach(marcRecordToChange::removeVariableField);
} else if (detail.getField().getSubfields().getFirst().getSubfield().charAt(0) == ANY_CHAR) {
marcRecordToChange.getDataFields().stream()
.filter(field -> fieldMatches(field, fieldTag, ind1, ind2))
.filter(field -> !applyProtection || isNotProtected(field))
.toList()
.forEach(fieldToDelete -> marcRecordToChange.removeVariableField(fieldToDelete));
} else {
char subfieldCode = detail.getField().getSubfields().getFirst().getSubfield().charAt(0);
marcRecordToChange.getDataFields().stream()
.filter(field -> fieldMatches(field, fieldTag, ind1, ind2))
.filter(field -> !applyProtection || isNotProtected(field))
.map(targetField -> {
targetField.removeSubfield(targetField.getSubfield(subfieldCode));
return targetField;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2855,6 +2855,233 @@ void shouldRetainExistingRepeatableFieldWhenExistingIsProtectedAndHasNoIncomingF
testUpdateRecord(incomingParsedContent, existingParsedContent, existingParsedContent, mappingParameters);
}

// DELETE action during UPDATE mapping option tests

@Test
void shouldDeleteAllFieldOccurrencesWhenSubfieldIsWildcardDuringUpdate() throws IOException {
String incomingParsedContent =
"{\"leader\":\"01314nam 22003851a 4500\",\"fields\":[{\"001\":\"ybp7406411\"}]}";
String existingParsedContent =
"{\"leader\":\"01314nam 22003851a 4500\",\"fields\":[{\"001\":\"ybp7406411\"},{\"650\":{\"subfields\":"
+ "[{\"a\":\"Biology\"},{\"x\":\"Study and teaching\"}],\"ind1\":\" \",\"ind2\":\"0\"}},{\"650\":"
+ "{\"subfields\":[{\"a\":\"Zoology\"},{\"2\":\"fast\"}],\"ind1\":\" \",\"ind2\":\"7\"}}]}";

MarcMappingDetail deleteRule = new MarcMappingDetail()
.withOrder(0)
.withAction(MarcMappingDetail.Action.DELETE)
.withField(new MarcField()
.withField("650")
.withIndicator1("*")
.withIndicator2("*")
.withSubfields(List.of(new MarcSubfield().withSubfield("*"))));

MappingProfile mappingProfile = new MappingProfile()
.withMappingDetails(new MappingDetail()
.withMarcMappingOption(UPDATE)
.withMarcMappingDetails(List.of(deleteRule)));

String expectedParsedContent =
"{\"leader\":\"00049nam 22000371a 4500\",\"fields\":[{\"001\":\"ybp7406411\"}]}";
testMarcUpdating(incomingParsedContent, existingParsedContent, expectedParsedContent, mappingProfile);
}

@Test
void shouldDeleteOnlySubfieldFromFieldIfSameSubfieldSpecifiedInMappingDetailDuringUpdate() throws IOException {
String incomingParsedContent =
"{\"leader\":\"01314nam 22003851a 4500\",\"fields\":[{\"001\":\"ybp7406411\"}]}";
String existingParsedContent =
"{\"leader\":\"01314nam 22003851a 4500\",\"fields\":["
+ "{\"001\":\"ybp7406411\"},"
+ "{\"650\":{\"subfields\":[{\"a\":\"Biology\"},{\"x\":\"Study\"}],\"ind1\":\" \",\"ind2\":\"0\"}},"
+ "{\"650\":{\"subfields\":[{\"a\":\"Zoology\"},{\"2\":\"fast\"}],\"ind1\":\" \",\"ind2\":\"7\"}}]}";

MarcMappingDetail deleteRule = new MarcMappingDetail()
.withOrder(0)
.withAction(MarcMappingDetail.Action.DELETE)
.withField(new MarcField()
.withField("650")
.withIndicator1(" ")
.withIndicator2("7")
.withSubfields(List.of(new MarcSubfield().withSubfield("2"))));

MappingProfile mappingProfile = new MappingProfile()
.withMappingDetails(new MappingDetail()
.withMarcMappingOption(UPDATE)
.withMarcMappingDetails(List.of(deleteRule)));

String expectedParsedContent =
"{\"leader\":\"00104nam 22000611a 4500\",\"fields\":["
+ "{\"001\":\"ybp7406411\"},"
+ "{\"650\":{\"subfields\":[{\"a\":\"Biology\"},{\"x\":\"Study\"}],\"ind1\":\" \",\"ind2\":\"0\"}},"
+ "{\"650\":{\"subfields\":[{\"a\":\"Zoology\"}],\"ind1\":\" \",\"ind2\":\"7\"}}]}";
testMarcUpdating(incomingParsedContent, existingParsedContent, expectedParsedContent, mappingProfile);
}

@Test
void shouldDeleteSpecifiedSubfieldFromAllFieldsIfSpecifiedTagIsWildcardDuringUpdate() throws IOException {
String incomingParsedContent =
"{\"leader\":\"01314nam 22003851a 4500\",\"fields\":[{\"001\":\"ybp7406411\"}]}";
String existingParsedContent =
"{\"leader\":\"01314nam 22003851a 4500\",\"fields\":["
+ "{\"001\":\"ybp7406411\"},"
+ "{\"650\":{\"subfields\":[{\"a\":\"Zoology\"},{\"2\":\"fast\"}],\"ind1\":\" \",\"ind2\":\"7\"}},"
+ "{\"651\":{\"subfields\":[{\"a\":\"Marine biology\"},{\"2\":\"fast\"}],\"ind1\":\" \",\"ind2\":\"0\"}}]}";

MarcMappingDetail deleteRule = new MarcMappingDetail()
.withOrder(0)
.withAction(MarcMappingDetail.Action.DELETE)
.withField(new MarcField()
.withField("*")
.withIndicator1("*")
.withIndicator2("*")
.withSubfields(List.of(new MarcSubfield().withSubfield("2"))));

MappingProfile mappingProfile = new MappingProfile()
.withMappingDetails(new MappingDetail()
.withMarcMappingOption(UPDATE)
.withMarcMappingDetails(List.of(deleteRule)));

String expectedParsedContent =
"{\"leader\":\"00104nam 22000611a 4500\",\"fields\":["
+ "{\"001\":\"ybp7406411\"},"
+ "{\"650\":{\"subfields\":[{\"a\":\"Zoology\"}],\"ind1\":\" \",\"ind2\":\"7\"}},"
+ "{\"651\":{\"subfields\":[{\"a\":\"Marine biology\"}],\"ind1\":\" \",\"ind2\":\"0\"}}]}";
testMarcUpdating(incomingParsedContent, existingParsedContent, expectedParsedContent, mappingProfile);
}

@Test
void shouldNotDeleteProtectedFieldsIfSpecifiedSubfieldIsWildcardDuringUpdate() throws IOException {
String incomingParsedContent =
"{\"leader\":\"01314nam 22003851a 4500\",\"fields\":[{\"001\":\"ybp7406411\"}]}";
String existingParsedContent =
"{\"leader\":\"00110nam 22000611a 4500\",\"fields\":["
+ "{\"001\":\"ybp7406411\"},"
+ "{\"650\":{\"subfields\":[{\"a\":\"Biology\"},{\"x\":\"Study\"}],\"ind1\":\" \",\"ind2\":\"0\"}},"
+ "{\"650\":{\"subfields\":[{\"a\":\"Zoology\"},{\"2\":\"fast\"}],\"ind1\":\" \",\"ind2\":\"7\"}}]}";

MarcMappingDetail deleteRule = new MarcMappingDetail()
.withOrder(0)
.withAction(MarcMappingDetail.Action.DELETE)
.withField(new MarcField()
.withField("650")
.withIndicator1("*")
.withIndicator2("*")
.withSubfields(List.of(new MarcSubfield().withSubfield("*"))));

MappingProfile mappingProfile = new MappingProfile()
.withMappingDetails(new MappingDetail()
.withMarcMappingOption(UPDATE)
.withMarcMappingDetails(List.of(deleteRule)));

List<MarcFieldProtectionSetting> protectionSettings = List.of(
new MarcFieldProtectionSetting()
.withField("650")
.withIndicator1("*")
.withIndicator2("*")
.withSubfield("a")
.withData("*"));

MappingParameters mappingParameters = new MappingParameters()
.withMarcFieldProtectionSettings(protectionSettings);

testMarcUpdating(incomingParsedContent, existingParsedContent, existingParsedContent, mappingParameters,
mappingProfile);
}

@Test
@SuppressWarnings("checkstyle:LineLength")
void shouldNotDeleteSubfieldFromProtectedFieldIfSameSubfieldSpecifiedInMappingDetailDuringUpdate() throws IOException {
String incomingParsedContent =
"{\"leader\":\"01314nam 22003851a 4500\",\"fields\":[{\"001\":\"ybp7406411\"}]}";
String existingParsedContent =
"{\"leader\":\"00110nam 22000611a 4500\",\"fields\":["
+ "{\"001\":\"ybp7406411\"},"
+ "{\"650\":{\"subfields\":[{\"a\":\"Biology\"},{\"x\":\"Study\"}],\"ind1\":\" \",\"ind2\":\"0\"}},"
+ "{\"650\":{\"subfields\":[{\"a\":\"Zoology\"},{\"2\":\"fast\"}],\"ind1\":\" \",\"ind2\":\"7\"}}]}";

MarcMappingDetail deleteRule = new MarcMappingDetail()
.withOrder(0)
.withAction(MarcMappingDetail.Action.DELETE)
.withField(new MarcField()
.withField("650")
.withIndicator1(" ")
.withIndicator2("7")
.withSubfields(List.of(new MarcSubfield().withSubfield("2"))));

MappingProfile mappingProfile = new MappingProfile()
.withMappingDetails(new MappingDetail()
.withMarcMappingOption(UPDATE)
.withMarcMappingDetails(List.of(deleteRule)));

List<MarcFieldProtectionSetting> protectionSettings = List.of(
new MarcFieldProtectionSetting()
.withField("650")
.withIndicator1("*")
.withIndicator2("7")
.withSubfield("*")
.withData("*"));

MappingParameters mappingParameters = new MappingParameters()
.withMarcFieldProtectionSettings(protectionSettings);

testMarcUpdating(incomingParsedContent, existingParsedContent, existingParsedContent, mappingParameters,
mappingProfile);
}

@Test
void shouldDeleteSpecifiedControlFieldDuringUpdate() throws IOException {
String incomingParsedContent =
"{\"leader\":\"01314nam 22003851a 4500\",\"fields\":[{\"001\":\"ybp7406411\"}]}";
String existingParsedContent =
"{\"leader\":\"00068nam 22000491a 4500\",\"fields\":[{\"001\":\"ybp7406411\"},{\"007\":\"vz|cza\"}]}";

MarcMappingDetail deleteRule = new MarcMappingDetail()
.withOrder(0)
.withAction(MarcMappingDetail.Action.DELETE)
.withField(new MarcField().withField("007"));

MappingProfile mappingProfile = new MappingProfile()
.withMappingDetails(new MappingDetail()
.withMarcMappingOption(UPDATE)
.withMarcMappingDetails(List.of(deleteRule)));

String expectedParsedContent =
"{\"leader\":\"00049nam 22000371a 4500\",\"fields\":[{\"001\":\"ybp7406411\"}]}";
testMarcUpdating(incomingParsedContent, existingParsedContent, expectedParsedContent, mappingProfile);
}

@Test
void shouldNotDeleteProtectedControlFieldDuringUpdate() throws IOException {
String incomingParsedContent =
"{\"leader\":\"01314nam 22003851a 4500\",\"fields\":[{\"001\":\"ybp7406411\"}]}";
String existingParsedContent =
"{\"leader\":\"00068nam 22000491a 4500\",\"fields\":[{\"001\":\"ybp7406411\"},{\"007\":\"vz|cza\"}]}";

MarcMappingDetail deleteRule = new MarcMappingDetail()
.withOrder(0)
.withAction(MarcMappingDetail.Action.DELETE)
.withField(new MarcField().withField("007"));

MappingProfile mappingProfile = new MappingProfile()
.withMappingDetails(new MappingDetail()
.withMarcMappingOption(UPDATE)
.withMarcMappingDetails(List.of(deleteRule)));

List<MarcFieldProtectionSetting> protectionSettings = List.of(
new MarcFieldProtectionSetting()
.withField("007")
.withIndicator1("")
.withIndicator2("")
.withSubfield("")
.withData("*"));

MappingParameters mappingParameters = new MappingParameters()
.withMarcFieldProtectionSettings(protectionSettings);

testMarcUpdating(incomingParsedContent, existingParsedContent, existingParsedContent, mappingParameters,
mappingProfile);
}

@Test
void shouldReturnTrueWhenFieldTagAnyOf1xxFields() {
for (int i = 100; i < 200; i++) {
Expand Down
Loading