Skip to content
Merged
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
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
### Bug fixes
* DELETE_INCOMING repeatable field action not removing duplicate scalar values from string arrays ([MODDICORE-507](https://folio-org.atlassian.net/browse/MODDICORE-507))
* Fix 035 being split on update when same $a in incoming and existing ([MODSOURCE-1014](https://folio-org.atlassian.net/browse/MODSOURCE-1014))
* Fix StringIndexOutOfBoundsException and NPE when the target subfield is empty in a field mapping profile

### Tech Dept
* Migrate tests from JUnit 4 to JUnit 6
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ public void processUpdateMappingOption(List<MarcMappingDetail> marcMappingRules)
isNotEmpty(detail.getField().getIndicator2()) ? detail.getField().getIndicator2().charAt(0)
: BLANK_SUBFIELD_CODE;
String subfieldCode = detail.getField().getSubfields().getFirst().getSubfield();
if (isEmpty(subfieldCode)) {
LOGGER.warn("processUpdateOption:: skipping UPDATE rule for field '{}': subfield code is not specified",
fieldTag);
continue;
}

Stream<DataField> incomingDataFields = incomingMarcRecord.getDataFields().stream()
.filter(field -> fieldMatches(field, fieldTag, ind1, ind2, subfieldCode.charAt(0)));
Expand Down Expand Up @@ -363,6 +368,12 @@ private MarcReader buildMarcReader(org.folio.Record marcRecord) {

private void processModifyMappingOption(List<MarcMappingDetail> mappingDetails) {
for (MarcMappingDetail mappingDetail : mappingDetails) {
if (mappingDetail.getField().getSubfields().isEmpty()
&& !Verifier.isControlField(mappingDetail.getField().getField())) {
LOGGER.warn("processModifyMappingOption:: skipping '{}' rule for field '{}': subfields list is empty",
mappingDetail.getAction(), mappingDetail.getField().getField());
continue;
}
switch (mappingDetail.getAction()) {
case ADD:
processAddAction(mappingDetail);
Expand Down Expand Up @@ -398,6 +409,10 @@ private void processAddAction(MarcMappingDetail detail) {
DataField dataField = marcFactory.newDataField(fieldTag, ind1, ind2);

for (MarcSubfield subfield : detail.getField().getSubfields()) {
if (isEmpty(subfield.getSubfield())) {
LOGGER.warn("processAddAction:: skipping subfield for field '{}': subfield code is not specified", fieldTag);
continue;
}
dataField.addSubfield(
marcFactory.newSubfield(subfield.getSubfield().charAt(0), subfield.getData().getText()));
}
Expand Down Expand Up @@ -470,24 +485,32 @@ private void processDeleteAction(MarcMappingDetail detail, boolean applyProtecti
.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;
})
.filter(field -> field.getSubfields().isEmpty())
.toList()
.forEach(targetField -> marcRecordToChange.removeVariableField(targetField));
String subfieldCodeStr = detail.getField().getSubfields().getFirst().getSubfield();
if (isEmpty(subfieldCodeStr)) {
LOGGER.warn("processDeleteAction:: skipping DELETE rule for field '{}': subfield code is not specified",
fieldTag);
return;
}
char subfieldCode = subfieldCodeStr.charAt(0);
if (subfieldCode == ANY_CHAR) {
marcRecordToChange.getDataFields().stream()
.filter(field -> fieldMatches(field, fieldTag, ind1, ind2))
.filter(field -> !applyProtection || isNotProtected(field))
.toList()
.forEach(fieldToDelete -> marcRecordToChange.removeVariableField(fieldToDelete));
} else {
marcRecordToChange.getDataFields().stream()
.filter(field -> fieldMatches(field, fieldTag, ind1, ind2))
.filter(field -> !applyProtection || isNotProtected(field))
.map(targetField -> {
targetField.removeSubfield(targetField.getSubfield(subfieldCode));
return targetField;
})
.filter(field -> field.getSubfields().isEmpty())
.toList()
.forEach(targetField -> marcRecordToChange.removeVariableField(targetField));
}
}
}

Expand Down Expand Up @@ -523,6 +546,10 @@ private void processInsert(MarcSubfield ruleSubfield, MarcMappingDetail mappingR
.filter(field -> fieldMatches(field, tag, ind1, ind2))
.toList();

if (isEmpty(ruleSubfield.getSubfield())) {
LOGGER.warn("processInsert:: skipping INSERT rule for field '{}': subfield code is not specified", tag);
return;
}
char subfieldCode = ruleSubfield.getSubfield().charAt(0);
for (DataField field : fieldsToEdit) {
List<Subfield> subfieldsToEdit =
Expand Down Expand Up @@ -638,7 +665,13 @@ private void replaceDataInDataFields(String tag, String dataToReplace, String re
char ind2 = isNotEmpty(mappingRule.getField().getIndicator2())
? mappingRule.getField().getIndicator2().charAt(0)
: BLANK_SUBFIELD_CODE;
char subfieldCode = mappingRule.getField().getSubfields().getFirst().getSubfield().charAt(0);
String subfieldCodeStr = mappingRule.getField().getSubfields().getFirst().getSubfield();
if (isEmpty(subfieldCodeStr)) {
LOGGER.warn("replaceDataInDataFields:: skipping REPLACE rule for field '{}': subfield code is not specified",
tag);
return;
}
char subfieldCode = subfieldCodeStr.charAt(0);

marcRecordToChange.getDataFields().stream()
.filter(field -> fieldMatches(field, tag, ind1, ind2, subfieldCode))
Expand Down Expand Up @@ -712,16 +745,21 @@ private void processMoveAction(MarcMappingDetail detail) {
private void moveDataToNewField(List<DataField> sourceFields, MarcSubfield subfieldRule) {
MarcField newFieldRule = subfieldRule.getData().getMarcField();
String newFieldTag = newFieldRule.getField();
if (isEmpty(subfieldRule.getSubfield())) {
LOGGER.warn("moveDataToNewField:: skipping MOVE rule for field '{}': subfield code is not specified",
newFieldRule.getField());
return;
}
char srcSubfieldCode = subfieldRule.getSubfield().charAt(0);
char newSubfieldCode =
newFieldRule.getSubfields().isEmpty() ? srcSubfieldCode
: newFieldRule.getSubfields().getFirst().getSubfield().charAt(0);
String firstNewSubfieldCode = newFieldRule.getSubfields().isEmpty()
? null : newFieldRule.getSubfields().getFirst().getSubfield();
char newSubfieldCode = isNotEmpty(firstNewSubfieldCode) ? firstNewSubfieldCode.charAt(0) : srcSubfieldCode;

for (DataField sourceField : sourceFields) {
char newFieldInd1 =
isNotEmpty(newFieldRule.getIndicator1()) ? newFieldRule.getIndicator1().charAt(0) : sourceField.getIndicator1();
char newFieldInd2 =
isNotEmpty(newFieldRule.getIndicator2()) ? newFieldRule.getIndicator1().charAt(0) : sourceField.getIndicator2();
isNotEmpty(newFieldRule.getIndicator2()) ? newFieldRule.getIndicator2().charAt(0) : sourceField.getIndicator2();
DataField newField = marcFactory.newDataField(newFieldTag, newFieldInd1, newFieldInd2);
List<Subfield> srcSubfields =
srcSubfieldCode == ANY_CHAR ? sourceField.getSubfields() : sourceField.getSubfields(srcSubfieldCode);
Expand All @@ -746,8 +784,15 @@ private void moveDataToExistingField(List<DataField> sourceFields, MarcSubfield
char existingFieldInd2 = isEmpty(subfieldRule.getData().getMarcField().getIndicator2()) ? BLANK_SUBFIELD_CODE
: subfieldRule.getData()
.getMarcField().getIndicator2().charAt(0);
if (isEmpty(subfieldRule.getSubfield())) {
LOGGER.warn("moveDataToExistingField:: skipping MOVE rule for field '{}': subfield code is not specified",
existingFieldTag);
return;
}
char srcSubfieldCode = subfieldRule.getSubfield().charAt(0);
char existingFieldSfCode = subfieldRule.getData().getMarcField().getSubfields().getFirst().getSubfield().charAt(0);
List<MarcSubfield> targetSubfields = subfieldRule.getData().getMarcField().getSubfields();
String existingFieldSfCodeStr = targetSubfields.isEmpty() ? null : targetSubfields.getFirst().getSubfield();
char existingFieldSfCode = isNotEmpty(existingFieldSfCodeStr) ? existingFieldSfCodeStr.charAt(0) : srcSubfieldCode;

List<DataField> existingFields = marcRecordToChange.getDataFields().stream()
.filter(field -> fieldMatches(field, existingFieldTag, existingFieldInd1, existingFieldInd2))
Expand Down
Loading
Loading