Skip to content

Commit

Permalink
MODSOURMAN-1228: Mechanism with happy-path works.
Browse files Browse the repository at this point in the history
  • Loading branch information
VRohach committed Oct 7, 2024
1 parent cc6f6f0 commit 2aab951
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 71 deletions.
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@
<path>${basedir}/ramls/settings/organization_collection.json</path>
<path>${basedir}/ramls/settings/subjectSources.json</path>
<path>${basedir}/ramls/settings/subjectTypes.json</path>
<path>${basedir}/ramls/settings/instanceDateTypes.json</path>
<path>${basedir}/ramls/settings/acquisitions_unit.json</path>
<path>${basedir}/ramls/settings/acquisitions_unit_collection.json</path>
<path>${basedir}/ramls/settings/acquisition_method.json</path>
Expand Down
17 changes: 17 additions & 0 deletions ramls/instance.json
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,23 @@
"$ref": "electronicAccess.json"
}
},
"dates": {
"type": "object",
"description": "Instance Dates",
"properties": {
"date1": {
"type": "string",
"description": "Date 1",
"maxLength": 4
},
"date2": {
"type": "string",
"description": "Date 2",
"maxLength": 4
}
},
"additionalProperties": false
},
"instanceTypeId": {
"type": "string",
"description": "The unique term for the resource type whether it's from the RDA content term list of locally defined"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

import java.util.LinkedHashMap;

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
Expand Down Expand Up @@ -201,7 +203,7 @@ private boolean checkOnIndicatorsCorrespondence(JsonObject subFieldMapping, Stri
}

private boolean checkOnIndicatorsMatches(JsonArray fieldMappingIndicators, String dataFieldInd1, String dataFieldInd2) {
for (int i=0; i < fieldMappingIndicators.size(); i++) {
for (int i = 0; i < fieldMappingIndicators.size(); i++) {
JsonObject indicatorsObj = fieldMappingIndicators.getJsonObject(i);
String subFieldMappingInd1 = indicatorsObj.getString(IND_1);
String subFieldMappingInd2 = indicatorsObj.getString(IND_2);
Expand Down Expand Up @@ -530,6 +532,17 @@ private void handleControlFieldRules(JsonArray controlFieldRules, ControlField c
continue;
}

if (BooleanUtils.isTrue(cfRule.getBoolean("createSingleObject"))) {
String target = cfRule.getString(TARGET);
String[] embeddedFields = target.split("\\.");
try {
buildSimpleJsonObject(entity, embeddedFields, data);
} catch (NoSuchFieldException | NoSuchMethodException | InvocationTargetException e) {
LOGGER.warn("Error:", rules.encode());
}
createNewComplexObj = false;
}
else{
//if conditionsMet = true, then all conditions of a specific rule were met
//and we can set the target to the rule's value
String target = cfRule.getString(TARGET);
Expand All @@ -542,6 +555,43 @@ private void handleControlFieldRules(JsonArray controlFieldRules, ControlField c
} else {
LOGGER.debug("handleControlFieldRules:: bad mapping {}", rules.encode());
}
}}
}

private void buildSimpleJsonObject(Object entity, String[] embeddedFields, String value)
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
Object currentObject = entity;
for (int i = 0; i < embeddedFields.length - 1; i++) {
Field field = currentObject.getClass().getDeclaredField(embeddedFields[i]);
field.setAccessible(true);
Object nextObject = field.get(currentObject);
if (nextObject == null) {
// If the next object in the path is null, instantiate it assuming it has a no-arg constructor
nextObject = field.getType().getDeclaredConstructor().newInstance();
field.set(currentObject, nextObject);
}
currentObject = nextObject;
}

// Set the value on the final field
Field targetField = currentObject.getClass().getDeclaredField(embeddedFields[embeddedFields.length - 1]);
targetField.setAccessible(true);
// Convert the string value to the appropriate type of the target field
Object convertedValue = convertStringToFieldType(value, targetField.getType());
targetField.set(currentObject, convertedValue);
}

private Object convertStringToFieldType(String value, Class<?> fieldType) throws IllegalArgumentException {
if (fieldType == String.class) {
return value;
} else if (fieldType == int.class || fieldType == Integer.class) {
return Integer.parseInt(value);
} else if (fieldType == double.class || fieldType == Double.class) {
return Double.parseDouble(value);
} else if (fieldType == boolean.class || fieldType == Boolean.class) {
return Boolean.parseBoolean(value);
} else {
throw new IllegalArgumentException("Unsupported field type for conversion: " + fieldType);
}
}

Expand Down Expand Up @@ -883,7 +933,7 @@ private static Method getMethod(Class<?> clazz, String methodName, Class<?>... p
}

private static ParameterizedType getParameterizedType(Field field) {
return PARAM_TYPE_CACHE.computeIfAbsent(field, fieldObj -> (ParameterizedType)fieldObj.getGenericType());
return PARAM_TYPE_CACHE.computeIfAbsent(field, fieldObj -> (ParameterizedType) fieldObj.getGenericType());
}

private static Object setObjectCorrectly(boolean newComp, Class<?> listTypeClass, Class<?> type, String pathSegment,
Expand Down Expand Up @@ -951,7 +1001,7 @@ private JsonArray addExtraMappingsForAuthorities(final DataField dataField, fina
final JsonArray extendedMapping = new JsonArray();
List<String> targets = retrieveTargetsFromControlSubfield(dataField);
List<LinkedHashMap<String, Object>> mappingList = regularMapping.getList();
targets.forEach(target -> extendedMapping.addAll(createAdditionalMappingsForTarget(target, mappingList)));
targets.forEach(target -> extendedMapping.addAll(createAdditionalMappingsForTarget(target, mappingList)));
extendedMapping.addAll(regularMapping);
return extendedMapping;
}
Expand All @@ -976,35 +1026,35 @@ private List<String> retrieveTargetsFromControlSubfield(DataField dataField) {

/**
* Constructs the list of rules to map relations like:
* {
* "entityPerRepeatedSubfield": false,
* "entity": [
* {
* "target": "saftBroaderTerm.headingRef",
* "description": "saftMeetingName",
* "subfield": ["a","c","d","n","q","g"],
* "exclusiveSubfield": ["t"],
* "rules": []
* },
* {
* "target": "saftBroaderTerm.headingType",
* "description": "meetingName",
* "subfield": ["a","c","d","n","q","g"],
* "exclusiveSubfield": ["t"],
* "rules": [
* {
* "conditions": [
* {
* "type": "set_heading_type_by_name",
* "parameter": {"name": "meetingName"}
* }
* ]
* }
* ],
* "applyRulesOnConcatenatedData": true
* }
* ]
* }
* {
* "entityPerRepeatedSubfield": false,
* "entity": [
* {
* "target": "saftBroaderTerm.headingRef",
* "description": "saftMeetingName",
* "subfield": ["a","c","d","n","q","g"],
* "exclusiveSubfield": ["t"],
* "rules": []
* },
* {
* "target": "saftBroaderTerm.headingType",
* "description": "meetingName",
* "subfield": ["a","c","d","n","q","g"],
* "exclusiveSubfield": ["t"],
* "rules": [
* {
* "conditions": [
* {
* "type": "set_heading_type_by_name",
* "parameter": {"name": "meetingName"}
* }
* ]
* }
* ],
* "applyRulesOnConcatenatedData": true
* }
* ]
* }
*/
private JsonArray createAdditionalMappingsForTarget(String target, List<LinkedHashMap<String, Object>> existingMappingList) {
JsonArray additionalMappings = new JsonArray();
Expand All @@ -1014,7 +1064,7 @@ private JsonArray createAdditionalMappingsForTarget(String target, List<LinkedHa
headingRefMapping.put(TARGET, target + ".headingRef");
headingRefMapping.put("description", existingMap.get(TARGET));

Map<String, Object> headingTypeMapping = new LinkedHashMap<>(existingMap);
Map<String, Object> headingTypeMapping = new LinkedHashMap<>(existingMap);
headingTypeMapping.put(TARGET, target + ".headingType");
headingTypeMapping.put("description", getHeadingType(existingMap.get(TARGET)));
headingTypeMapping.put("applyRulesOnConcatenatedData", true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,37 @@ public void testMarcToInstanceWithRepeatableSubjects() throws IOException {
});
}

@Test
public void testMarcToInstanceWith008Date() throws IOException {
MarcReader reader = new MarcStreamReader(new ByteArrayInputStream(TestUtil.readFileFromPath(BIB_WITH_REPEATED_600_SUBFIELDS).getBytes(StandardCharsets.UTF_8)));
JsonObject mappingRules = new JsonObject(TestUtil.readFileFromPath(DEFAULT_MAPPING_RULES_PATH));
String rawSubjectSources = TestUtil.readFileFromPath(DEFAULT_SUBJECT_SOURCES_PATH);
String rawSubjectTypes = TestUtil.readFileFromPath(DEFAULT_SUBJECT_TYPES_PATH);
List<SubjectSource> subjectSources = List.of(new ObjectMapper().readValue(rawSubjectSources, SubjectSource[].class));
List<SubjectType> subjectTypes = List.of(new ObjectMapper().readValue(rawSubjectTypes, SubjectType[].class));


ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
List<Instance> mappedInstances = new ArrayList<>();
while (reader.hasNext()) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
MarcJsonWriter writer = new MarcJsonWriter(os);
Record record = reader.next();
writer.write(record);
JsonObject marc = new JsonObject(os.toString());
Instance instance = mapper.mapRecord(marc, new MappingParameters().withSubjectSources(subjectSources).withSubjectTypes(subjectTypes), mappingRules);
mappedInstances.add(instance);
Validator validator = factory.getValidator();
Set<ConstraintViolation<Instance>> violations = validator.validate(instance);
assertTrue(violations.isEmpty());
}
assertFalse(mappedInstances.isEmpty());
assertEquals(1, mappedInstances.size());

Instance mappedInstance = mappedInstances.get(0);
assertNotNull(mappedInstance.getId());
}

@Test
public void testMarcToInstanceWithRepeatableSubjectsButWithoutIndicators() throws IOException {
final List<Subject> expectedResults = List.of(
Expand Down
Loading

0 comments on commit 2aab951

Please sign in to comment.