use of io.atlasmap.v2.FieldGroup in project atlasmap by atlasmap.
the class AtlasServiceTest method testProcessMapping.
@Test
public void testProcessMapping() throws Exception {
Response res = service.processMappingRequest(this.getClass().getClassLoader().getResourceAsStream("mappings/process-mapping-request.json"), generateTestUriInfo("http://localhost:8686/v2/atlas", "http://localhost:8686/v2/atlas/mapping/process"));
ProcessMappingResponse resp = Json.mapper().readValue((byte[]) res.getEntity(), ProcessMappingResponse.class);
assertEquals(0, resp.getAudits().getAudit().size(), printAudit(resp.getAudits()));
FieldGroup group = (FieldGroup) resp.getMapping().getOutputField().get(0);
assertEquals("/addressList<>/city", group.getPath());
Field f = group.getField().get(0);
assertEquals("/addressList<0>/city", f.getPath());
assertEquals("testZzz", f.getValue());
}
use of io.atlasmap.v2.FieldGroup in project atlasmap by atlasmap.
the class JsonFieldReader method getJsonFieldsForPath.
private List<Field> getJsonFieldsForPath(AtlasInternalSession session, JsonNode node, Field field, AtlasPath path, int depth) throws AtlasException {
List<Field> fields = new ArrayList<>();
List<SegmentContext> segments = path.getSegments(true);
if (segments.size() < depth) {
throw new AtlasException(String.format("depth '%s' exceeds segment size '%s'", depth, segments.size()));
}
if (segments.size() == depth) {
// if traversed the entire path and found value
if (field.getFieldType() == FieldType.COMPLEX && !node.isValueNode()) {
FieldGroup group = (FieldGroup) field;
populateChildFields(session, node, group, path);
fields.add(group);
} else {
JsonField jsonField = new JsonField();
AtlasModelFactory.copyField(field, jsonField, true);
if (field instanceof JsonEnumField && field.getFieldType() == FieldType.COMPLEX) {
// enum has COMPLEX by default
jsonField.setFieldType(FieldType.STRING);
}
Object value = handleValueNode(session, node, jsonField);
jsonField.setValue(value);
// reset index for subfields
jsonField.setIndex(null);
fields.add(jsonField);
}
return fields;
}
// segments.size() > depth
SegmentContext segmentContext;
JsonNode child;
if (depth == 0 && path.hasCollectionRoot()) {
// if root is a collection
child = node;
segmentContext = segments.get(depth);
} else {
if (depth == 0) {
if (node.size() == 1 && !path.getSegments(false).get(0).getExpression().startsWith(rootNode.fieldNames().next())) {
// peel off a rooted object, i.e. mapping /orderId works for document { source: { orderId: 123 } }
node = node.elements().next();
}
if (segments.size() > 1) {
// skip the root, if not a collection
depth = 1;
}
}
segmentContext = segments.get(depth);
String fieldName = segmentContext.getName();
child = node.get(fieldName);
}
if (child == null) {
return fields;
}
if (segmentContext.getCollectionType() == CollectionType.NONE) {
List<Field> childFields = getJsonFieldsForPath(session, child, field, path, depth + 1);
fields.addAll(childFields);
return fields;
}
// collection
if (segmentContext.getCollectionIndex() != null) {
if (child.size() <= segmentContext.getCollectionIndex()) {
// index out of range
return fields;
}
List<Field> arrayFields = getJsonFieldsForPath(session, child.get(segmentContext.getCollectionIndex()), field, path, depth + 1);
fields.addAll(arrayFields);
} else {
// if index not included, iterate over all
for (int i = 0; i < child.size(); i++) {
Field itemField;
if (field instanceof FieldGroup) {
itemField = AtlasJsonModelFactory.cloneFieldGroup((FieldGroup) field);
AtlasPath.setCollectionIndexRecursively((FieldGroup) itemField, depth, i);
} else {
itemField = AtlasJsonModelFactory.cloneField((JsonField) field, false);
AtlasPath itemPath = new AtlasPath(field.getPath());
itemPath.setCollectionIndex(depth, i);
itemField.setPath(itemPath.toString());
}
List<Field> arrayFields = getJsonFieldsForPath(session, child.get(i), itemField, new AtlasPath(itemField.getPath()), depth + 1);
fields.addAll(arrayFields);
}
}
return fields;
}
use of io.atlasmap.v2.FieldGroup in project atlasmap by atlasmap.
the class JsonFieldReader method read.
@Override
public Field read(AtlasInternalSession session) throws AtlasException {
Field field = session.head().getSourceField();
if (rootNode == null) {
AtlasUtil.addAudit(session, field, String.format("Cannot read a field '%s' of JSON document '%s', document is null", field.getPath(), field.getDocId()), AuditStatus.ERROR, null);
return field;
}
AtlasPath path = new AtlasPath(field.getPath());
List<Field> fields = getJsonFieldsForPath(session, rootNode, field, path, 0);
if (path.hasCollection() && !path.isIndexedCollection()) {
FieldGroup fieldGroup = AtlasModelFactory.createFieldGroupFrom(field, true);
fieldGroup.getField().addAll(fields);
session.head().setSourceField(fieldGroup);
return fieldGroup;
} else if (fields.size() == 1) {
field.setValue(fields.get(0).getValue());
return field;
} else {
return field;
}
}
use of io.atlasmap.v2.FieldGroup in project atlasmap by atlasmap.
the class JavaModule method populateTargetField.
@Override
public void populateTargetField(AtlasInternalSession session) throws AtlasException {
Field sourceField = session.head().getSourceField();
Field targetField = session.head().getTargetField();
AtlasPath path = new AtlasPath(targetField.getPath());
FieldGroup targetFieldGroup = null;
if (path.hasCollection() && !path.isIndexedCollection()) {
targetFieldGroup = AtlasModelFactory.createFieldGroupFrom(targetField, true);
session.head().setTargetField(targetFieldGroup);
}
JavaFieldWriter writer = session.getFieldWriter(getDocId(), JavaFieldWriter.class);
if (targetFieldGroup == null) {
if (sourceField instanceof FieldGroup) {
List<Field> subFields = ((FieldGroup) sourceField).getField();
if (subFields == null || subFields.size() == 0) {
return;
}
Integer index = targetField.getIndex();
if (index != null) {
if (subFields.size() > index) {
sourceField = subFields.get(index);
} else {
AtlasUtil.addAudit(session, getDocId(), String.format("The number of source fields (%s) is smaller than target index (%s) - ignoring", subFields.size(), index), AuditStatus.WARN, null);
return;
}
} else {
// The last one wins for compatibility
sourceField = subFields.get(subFields.size() - 1);
}
session.head().setSourceField(sourceField);
}
/* Lazy parent instantiation, unless specific mapping defined for a complex type (Example json -> java)
Only instantiate the parent if there is a child value to avoid null src class -> empty dst class mapping
This will ensure null src class maps to null destination class
*/
Object parentObject = null;
if (null != sourceField.getValue() || (null == sourceField.getValue() && targetField.getFieldType() == FieldType.COMPLEX && !(targetField instanceof JavaEnumField))) {
parentObject = writer.prepareParentObject(session);
}
if (parentObject != null) {
writer.populateTargetFieldValue(session, parentObject);
writer.enqueueFieldAndParent(targetField, parentObject);
}
} else if (sourceField instanceof FieldGroup) {
if (((FieldGroup) sourceField).getField().size() == 0) {
Object parentObject = writer.prepareParentObject(session);
if (parentObject != null) {
writer.enqueueFieldAndParent(targetFieldGroup, parentObject);
}
}
Field previousTargetSubField = null;
for (int i = 0; i < ((FieldGroup) sourceField).getField().size(); i++) {
Field sourceSubField = ((FieldGroup) sourceField).getField().get(i);
Field targetSubField = targetField instanceof JavaEnumField ? new JavaEnumField() : new JavaField();
AtlasJavaModelFactory.copyField(targetField, targetSubField, false);
getCollectionHelper().copyCollectionIndexes(sourceField, sourceSubField, targetSubField, previousTargetSubField);
previousTargetSubField = targetSubField;
targetFieldGroup.getField().add(targetSubField);
session.head().setSourceField(sourceSubField);
session.head().setTargetField(targetSubField);
Object parentObject = writer.prepareParentObject(session);
if (parentObject != null) {
writer.populateTargetFieldValue(session, parentObject);
writer.enqueueFieldAndParent(targetSubField, parentObject);
}
}
session.head().setSourceField(sourceField);
session.head().setTargetField(targetFieldGroup);
} else {
Field targetSubField = targetField instanceof JavaEnumField ? new JavaEnumField() : new JavaField();
AtlasJavaModelFactory.copyField(targetField, targetSubField, false);
path.setVacantCollectionIndex(0);
targetSubField.setPath(path.toString());
targetFieldGroup.getField().add(targetSubField);
session.head().setTargetField(targetSubField);
Object parentObject = writer.prepareParentObject(session);
if (parentObject != null) {
writer.populateTargetFieldValue(session, parentObject);
writer.enqueueFieldAndParent(targetSubField, parentObject);
}
session.head().setTargetField(targetFieldGroup);
}
if (LOG.isDebugEnabled()) {
LOG.debug("{}: processTargetFieldMapping completed: SourceField:[docId={}, path={}, type={}, value={}], TargetField:[docId={}, path={}, type={}, value={}]", getDocId(), sourceField.getDocId(), sourceField.getPath(), sourceField.getFieldType(), sourceField.getValue(), targetField.getDocId(), targetField.getPath(), targetField.getFieldType(), targetField.getValue());
}
}
use of io.atlasmap.v2.FieldGroup in project atlasmap by atlasmap.
the class AtlasJavaModelFactory method cloneJavaField.
/**
* Clones {@link JavaField} or {@link JavaEnumField}.
* @param field field
* @param withActions true to clone actions as well
* @return cloned
*/
public static Field cloneJavaField(Field field, boolean withActions) {
if (field instanceof FieldGroup) {
FieldGroup clone = AtlasModelFactory.createFieldGroupFrom(field, withActions);
for (Field f : ((FieldGroup) field).getField()) {
clone.getField().add(cloneJavaField(f, withActions));
}
return clone;
}
Field clone = field instanceof JavaEnumField ? new JavaEnumField() : new JavaField();
copyField(field, clone, withActions);
return clone;
}
Aggregations