Skip to content

Commit

Permalink
fix: one_to_many mapping - repeat source value based on count
Browse files Browse the repository at this point in the history
  • Loading branch information
shanthi4647 authored and rkorytkowski committed Aug 25, 2020
1 parent 90017fa commit 84fc268
Show file tree
Hide file tree
Showing 11 changed files with 326 additions and 40 deletions.
Expand Up @@ -33,6 +33,7 @@
import io.atlasmap.v2.PadStringLeft;
import io.atlasmap.v2.PadStringRight;
import io.atlasmap.v2.Prepend;
import io.atlasmap.v2.Repeat;
import io.atlasmap.v2.ReplaceAll;
import io.atlasmap.v2.ReplaceFirst;
import io.atlasmap.v2.Split;
Expand Down Expand Up @@ -80,7 +81,7 @@ public static String concatenate(Concatenate concat, List<String> inputs) {
if (entry != null) {
builder.append(entry);
}
isFirst =false;
isFirst = false;
}

return builder.toString();
Expand Down Expand Up @@ -204,6 +205,26 @@ public static String[] split(Split split, String input) {
return input == null ? null : input.toString().split(split.getDelimiter());
}

@AtlasActionProcessor(sourceType = FieldType.ANY)
public static String[] repeat(Repeat repeat, String input) {

if (repeat == null) {
throw new IllegalArgumentException("repeat is not defined");
}

String[] returnObj = null;

// Repeat the value based on count
int count = repeat.getCount();

returnObj = new String[count];
for (int i = 0; i < count; i++) {
returnObj[i] = input;
}

return returnObj;
}

@AtlasActionProcessor
public static Boolean startsWith(StartsWith startsWith, String input) {
if (startsWith == null || startsWith.getString() == null) {
Expand Down
Expand Up @@ -627,26 +627,31 @@ private Object flattenList(Object value) {
}

public Object buildAndProcessAction(ActionProcessor actionProcessor, Map<String, Object> actionParameters, List<Field> fields) {
List<Object> flattenedValue = new ArrayList<>();
List<Object> flattenedValues = new ArrayList<>();
for (Field item : fields) {
if (item instanceof FieldGroup) {
FieldGroup fieldGroup = (FieldGroup)item;
List<Object> values = new ArrayList<>();
extractNestedListValuesFromFieldGroup(fieldGroup, values); //preserve top level list of parameters and arguments
flattenedValue.addAll(values);
flattenedValues.addAll(values);
} else {
flattenedValue.add((item).getValue());
flattenedValues.add(item.getValue());
}
}
FieldType valueType = determineFieldType(flattenedValue);
Object sourceObject = flattenedValues;
if (flattenedValues.size() == 1) {
sourceObject = flattenedValues.get(0); //it is a single value so do not pass it as a collection
}

FieldType valueType = determineFieldType(flattenedValues);
try {
Action action = actionProcessor.getActionClass().newInstance();
for (Map.Entry<String, Object> property : actionParameters.entrySet()) {
String setter = "set" + property.getKey().substring(0, 1).toUpperCase() + property.getKey().substring(1);
action.getClass().getMethod(setter, property.getValue().getClass()).invoke(action, property.getValue());
}

return processAction(action, actionProcessor, valueType, flattenedValue);
return processAction(action, actionProcessor, valueType, sourceObject);
} catch (Exception e) {
throw new IllegalArgumentException(String.format("The action '%s' cannot be processed", actionProcessor.getActionDetail().getName()), e);
}
Expand Down Expand Up @@ -710,48 +715,33 @@ public Field processActions(AtlasInternalSession session, Field field) throws At
}
}

if (fieldGroup != null) {
if (tmpSourceObject instanceof List) {
// n -> n - reuse passed-in FieldGroup
List<?> sourceList = (List<?>) tmpSourceObject;
Field lastSubField = null;
FieldGroup existingFieldGroup = fieldGroup;
if (field instanceof FieldGroup) {
existingFieldGroup = (FieldGroup) field;
}
if (tmpSourceObject instanceof List) {
// n -> n and 1 -> n - create new FieldGroup
fieldGroup = AtlasModelFactory.createFieldGroupFrom(field, false);

// Make sure fieldGroup is of a collection type
if (fieldGroup.getCollectionType() == null || CollectionType.NONE.equals(fieldGroup.getCollectionType())) {
fieldGroup.setCollectionType(CollectionType.ARRAY);
fieldGroup.setPath(fieldGroup.getPath() + "[]");
}

for (int i = 0; i < sourceList.size(); i++) {
if (existingFieldGroup.getField().size() > i) {
lastSubField = existingFieldGroup.getField().get(i);
} else {
Field subField = new SimpleField();
AtlasModelFactory.copyField(lastSubField, subField, true);
existingFieldGroup.getField().add(subField);
lastSubField = subField;
}
lastSubField.setValue(sourceList.get(i));
lastSubField.setFieldType(currentType);
}
field = existingFieldGroup;
} else {
// n -> 1 - create new Field
Field newField = new SimpleField();
AtlasModelFactory.copyField(field, newField, false);
newField.setValue(tmpSourceObject);
newField.setFieldType(currentType);
field = newField;
}
} else if (tmpSourceObject instanceof List) {
// 1 -> n - create new FieldGroup
fieldGroup = AtlasModelFactory.createFieldGroupFrom(field, true);
for (Object subValue : (List<?>) tmpSourceObject) {
Field subField = new SimpleField();
AtlasModelFactory.copyField(field, subField, false);
AtlasModelFactory.copyField(fieldGroup, subField, false);
subField.setIndex(null);
subField.setValue(subValue);
subField.setFieldType(currentType);
subField.setCollectionType(CollectionType.NONE);
fieldGroup.getField().add(subField);
}
field = fieldGroup;
} else if (fieldGroup != null) {
// n -> 1 - create new Field
Field newField = new SimpleField();
AtlasModelFactory.copyField(field, newField, false);
newField.setValue(tmpSourceObject);
newField.setFieldType(currentType);
field = newField;
} else {
// 1 -> 1 = reuse passed-in Field
field.setValue(tmpSourceObject);
Expand Down
Expand Up @@ -301,4 +301,68 @@ public void testAdd() throws Exception {
assertEquals(2+4+6+8, target.getIntField());
}

@Test
public void testActionRepeat_1() throws Exception {
URL url = Thread.currentThread().getContextClassLoader().getResource("mappings/atlasmapping-multiplicity-transformation-action_repeat.json");
AtlasMapping mapping = mappingService.loadMapping(url);
AtlasContext context = DefaultAtlasContextFactory.getInstance().createContext(mapping);
AtlasSession session = context.createSession();
String sourceJson = new String(Files.readAllBytes(Paths.get(
Thread.currentThread().getContextClassLoader().getResource("data/json-source-repeat.json").toURI())));
session.setSourceDocument("json-source-repeat", sourceJson);

context.process(session);
assertFalse(TestHelper.printAudit(session), session.hasErrors());
Object output = session.getTargetDocument("json-target");
assertEquals("[{\"targetField\":\"simpleFieldValue\"}]", output);
}

@Test
public void testActionRepeatCount3() throws Exception {
URL url = Thread.currentThread().getContextClassLoader().getResource("mappings/atlasmapping-multiplicity-transformation-action_repeat.json");
AtlasMapping mapping = mappingService.loadMapping(url);
AtlasContext context = DefaultAtlasContextFactory.getInstance().createContext(mapping);
AtlasSession session = context.createSession();
String sourceJson = new String(Files.readAllBytes(Paths.get(
Thread.currentThread().getContextClassLoader().getResource("data/json-source-repeat_count_3.json").toURI())));
session.setSourceDocument("json-source-repeat", sourceJson);

context.process(session);
assertFalse(TestHelper.printAudit(session), session.hasErrors());
Object output = session.getTargetDocument("json-target");
assertEquals("[{\"targetField\":\"simpleFieldValue\"},{\"targetField\":\"simpleFieldValue\"},{\"targetField\":\"simpleFieldValue\"}]", output);
}

@Test
public void testActionRepeatForNoSourceField() throws Exception {
URL url = Thread.currentThread().getContextClassLoader().getResource("mappings/atlasmapping-multiplicity-transformation-action_repeat.json");
AtlasMapping mapping = mappingService.loadMapping(url);
AtlasContext context = DefaultAtlasContextFactory.getInstance().createContext(mapping);
AtlasSession session = context.createSession();
String sourceJson = new String(Files.readAllBytes(Paths.get(
Thread.currentThread().getContextClassLoader().getResource("data/json-source-repeat_no_field.json").toURI())));
session.setSourceDocument("json-source-repeat", sourceJson);

context.process(session);
assertFalse(TestHelper.printAudit(session), session.hasErrors());
Object output = session.getTargetDocument("json-target");
assertEquals("[]", output);
}

@Test
public void testActionRepeatForNestedCollectionField() throws Exception {
URL url = Thread.currentThread().getContextClassLoader().getResource("mappings/atlasmapping-multiplicity-transformation-action_repeat_nested_collection.json");
AtlasMapping mapping = mappingService.loadMapping(url);
AtlasContext context = DefaultAtlasContextFactory.getInstance().createContext(mapping);
AtlasSession session = context.createSession();
String sourceJson = new String(Files.readAllBytes(Paths.get(
Thread.currentThread().getContextClassLoader().getResource("data/json-source-repeat_for_nested_collection_field.json").toURI())));
session.setSourceDocument("json-source-repeat", sourceJson);

context.process(session);
assertFalse(TestHelper.printAudit(session), session.hasErrors());
Object output = session.getTargetDocument("json-target");
assertEquals("[{\"targetField\":\"simpleFieldValue\"},{\"targetField\":\"simpleFieldValue\"},{\"targetField\":\"simpleFieldValue\"}]", output);
}

}
@@ -0,0 +1,8 @@
{
"simpleField": "simpleFieldValue",
"rootArray":[
{
"arrayField": ""
}
]
}
@@ -0,0 +1,14 @@
{
"simpleField": "simpleFieldValue",
"rootArray":[
{
"arrayField": ""
},
{
"arrayField": ""
},
{
"arrayField": ""
}
]
}
@@ -0,0 +1,18 @@
{
"simpleField": "simpleFieldValue",
"rootArray": [
{
"nestedArray": [
{
"arrayField": "dt1"
},
{
"arrayField": "dt2"
},
{
"arrayField": "dt2"
}
]
}
]
}
@@ -0,0 +1,7 @@
{
"simpleField": "simpleFieldValue",
"rootArray":[
{
}
]
}
@@ -0,0 +1,70 @@
{
"AtlasMapping": {
"jsonType": "io.atlasmap.v2.AtlasMapping",
"dataSource": [
{
"jsonType": "io.atlasmap.json.v2.JsonDataSource",
"id": "json-source-repeat",
"uri": "atlas:json:json-source-repeat",
"dataSourceType": "SOURCE"
},
{
"jsonType": "io.atlasmap.json.v2.JsonDataSource",
"id": "json-target",
"uri": "atlas:json:json-target",
"dataSourceType": "TARGET"
}
],
"mappings": {
"mapping": [
{
"jsonType": "io.atlasmap.v2.Mapping",
"expression": "REPEAT(count(${json-source-repeat:/rootArray<>/arrayField}), ${json-source-repeat:/simpleField})",
"inputFieldGroup": {
"jsonType": "io.atlasmap.v2.FieldGroup",
"field": [
{
"jsonType": "io.atlasmap.json.v2.JsonField",
"docId": "json-source-repeat",
"index": 0,
"path": "/simpleField",
"fieldType": "STRING",
"name": "simpleField"
},
{
"jsonType": "io.atlasmap.json.v2.JsonField",
"docId": "json-source-repeat",
"index": 1,
"path": "/rootArray<>/arrayField",
"fieldType": "STRING",
"name": "DT"
}
]
},
"inputField" : [ ],
"outputField": [
{
"jsonType": "io.atlasmap.json.v2.JsonField",
"docId": "json-target",
"index": 0,
"path": "/[]/targetField",
"fieldType": "STRING",
"name": "targetField"
}
],
"id": "mapping.88333"
}
]
},
"lookupTables": {
"lookupTable": []
},
"constants": {
"constant": []
},
"properties": {
"property": []
},
"name": "UI.158101"
}
}

0 comments on commit 84fc268

Please sign in to comment.