use of io.atlasmap.core.AtlasPath in project atlasmap by atlasmap.
the class KafkaConnectFieldReader method read.
@Override
public Field read(AtlasInternalSession session) throws AtlasException {
Field field = session.head().getSourceField();
if (root == null) {
AtlasUtil.addAudit(session, field, String.format("Cannot read a field '%s' of KafkaConnect document '%s', document is null", field.getPath(), field.getDocId()), AuditStatus.ERROR, null);
return field;
}
AtlasPath path = new AtlasPath(field.getPath());
List<Field> fields;
if (path.getSegments(true).size() == 1) {
if (field.getFieldType() == FieldType.COMPLEX) {
FieldGroup group = (FieldGroup) field;
if (path.isCollectionRoot()) {
nestComplexCollection(session, (List<Object>) root, group, 0);
} else {
populateChildFields(session, (Struct) root, group);
}
return group;
} else {
fields = createValueFields(root, path.getRootSegment(), 0, (KafkaConnectField) field);
}
} else {
fields = getFieldsForPath(session, root, 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 f = fields.get(0);
session.head().setSourceField(f);
return f;
} else {
return field;
}
}
use of io.atlasmap.core.AtlasPath in project atlasmap by atlasmap.
the class KafkaConnectFieldReader method populateChildFields.
private void populateChildFields(AtlasInternalSession session, Struct parent, FieldGroup fieldGroup) throws AtlasException {
List<Field> newChildren = new ArrayList<>();
for (Field child : fieldGroup.getField()) {
AtlasPath childPath = new AtlasPath(child.getPath());
Object childValue = parent.get(childPath.getLastSegment().getName());
if (childPath.getLastSegment().getCollectionType() != CollectionType.NONE) {
FieldGroup childGroup = populateCollectionItems(session, (List<Object>) childValue, child);
newChildren.add(childGroup);
} else {
if (child instanceof FieldGroup) {
populateChildFields(session, (Struct) childValue, (FieldGroup) child);
} else {
Object converted = conversionService.convertType(childValue, child.getFormat(), child.getFieldType(), null);
child.setValue(converted);
}
newChildren.add(child);
}
}
fieldGroup.getField().clear();
fieldGroup.getField().addAll(newChildren);
}
use of io.atlasmap.core.AtlasPath in project atlasmap by atlasmap.
the class KafkaConnectFieldReader method createValueFields.
private List<Field> createValueFields(Object parent, SegmentContext segment, int segmentIndex, KafkaConnectField parentField) throws AtlasException {
List<Field> fields = new LinkedList<>();
if (segment.getCollectionType() == CollectionType.NONE) {
KafkaConnectField kcField = AtlasKafkaConnectModelFactory.cloneField(parentField, true);
Object converted = conversionService.convertType(parent, parentField.getFormat(), parentField.getFieldType(), null);
kcField.setValue(converted);
// reset index for subfields
kcField.setIndex(null);
fields.add(kcField);
} else if (segment.getCollectionIndex() != null) {
List<Object> collection = (List<Object>) parent;
int i = segment.getCollectionIndex();
KafkaConnectField kcField = AtlasKafkaConnectModelFactory.cloneField(parentField, true);
Object converted = conversionService.convertType(collection.get(i), parentField.getFormat(), parentField.getFieldType(), null);
kcField.setValue(converted);
// reset index for subfields
kcField.setIndex(null);
fields.add(kcField);
} else {
List<Object> collection = (List<Object>) parent;
for (int i = 0; i < collection.size(); i++) {
KafkaConnectField kcField = AtlasKafkaConnectModelFactory.cloneField(parentField, true);
Object converted = conversionService.convertType(collection.get(i), parentField.getFormat(), parentField.getFieldType(), null);
kcField.setValue(converted);
// reset index for subfields
kcField.setIndex(null);
fields.add(kcField);
AtlasPath path = new AtlasPath(parentField.getPath());
path.setCollectionIndex(segmentIndex, i);
kcField.setPath(path.toString());
}
}
return fields;
}
use of io.atlasmap.core.AtlasPath in project atlasmap by atlasmap.
the class KafkaConnectFieldReader method getFieldsForPath.
private List<Field> getFieldsForPath(AtlasInternalSession session, Object parent, Field field, AtlasPath path, int depth) throws AtlasException {
List<Field> fields = new ArrayList<>();
List<SegmentContext> segments = path.getSegments(true);
if (parent == null) {
return fields;
}
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 instanceof FieldGroup && field.getFieldType() == FieldType.COMPLEX && (parent instanceof Struct)) {
FieldGroup group = (FieldGroup) field;
populateChildFields(session, (Struct) parent, group);
fields.add(group);
} else {
field.setValue(parent);
fields.add(field);
}
return fields;
}
// segments.size() > depth
SegmentContext segmentContext = null;
Object child = null;
List<Object> collectionChild = null;
if (depth == 0 && path.hasCollectionRoot()) {
// if root is a collection
collectionChild = (List<Object>) parent;
segmentContext = segments.get(depth);
} else {
if (depth == 0) {
// skip the root, if not a collection
depth = 1;
}
segmentContext = segments.get(depth);
String fieldName = segmentContext.getName();
child = ((Struct) parent).get(fieldName);
if (segmentContext.getCollectionType() != CollectionType.NONE) {
collectionChild = (List<Object>) child;
}
}
if (segmentContext.getCollectionType() == CollectionType.NONE) {
List<Field> childFields = getFieldsForPath(session, child, field, path, depth + 1);
fields.addAll(childFields);
return fields;
}
// collection
if (segmentContext.getCollectionIndex() != null) {
if (collectionChild.size() <= segmentContext.getCollectionIndex()) {
// index out of range
return fields;
}
List<Field> arrayFields = getFieldsForPath(session, collectionChild.get(segmentContext.getCollectionIndex()), field, path, depth + 1);
fields.addAll(arrayFields);
} else {
// if index not included, iterate over all
for (int i = 0; i < collectionChild.size(); i++) {
Field itemField;
if (field instanceof FieldGroup) {
itemField = AtlasKafkaConnectModelFactory.cloneFieldGroup((FieldGroup) field);
AtlasPath.setCollectionIndexRecursively((FieldGroup) itemField, depth, i);
} else {
itemField = AtlasKafkaConnectModelFactory.cloneField((KafkaConnectField) field, false);
AtlasPath itemPath = new AtlasPath(field.getPath());
itemPath.setCollectionIndex(depth, i);
itemField.setPath(itemPath.toString());
}
List<Field> arrayFields = getFieldsForPath(session, collectionChild.get(i), itemField, new AtlasPath(itemField.getPath()), depth + 1);
fields.addAll(arrayFields);
}
}
return fields;
}
use of io.atlasmap.core.AtlasPath in project atlasmap by atlasmap.
the class DocumentJavaFieldWriter method write.
public void write(AtlasInternalSession session) throws AtlasException {
LookupTable lookupTable = session.head().getLookupTable();
Field sourceField = session.head().getSourceField();
Field targetField = session.head().getTargetField();
try {
if (targetField == null) {
throw new AtlasException(new IllegalArgumentException("Argument 'field' cannot be null"));
}
String targetFieldClassName = (targetField instanceof JavaField) ? ((JavaField) targetField).getClassName() : ((JavaEnumField) targetField).getClassName();
if (LOG.isDebugEnabled()) {
LOG.debug("Now processing field: " + targetField);
LOG.debug("Field type: " + targetField.getFieldType());
LOG.debug("Field path: " + targetField.getPath());
LOG.debug("Field value: " + targetField.getValue());
LOG.debug("Field className: " + targetFieldClassName);
}
processedPaths.add(targetField.getPath());
AtlasPath path = new AtlasPath(targetField.getPath());
Object parentObject = rootObject;
boolean segmentIsComplexSegment = true;
for (SegmentContext segmentContext : path.getSegmentContexts(true)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Now processing segment: " + segmentContext);
LOG.debug("Parent object is currently: " + writeDocumentToString(false, parentObject));
}
if ("/".equals(segmentContext.getSegmentPath())) {
if (rootObject == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Creating root node: " + segmentContext);
}
rootObject = createParentObject(targetField, parentObject, segmentContext);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Root node already exists, skipping segment: " + segmentContext);
}
}
parentObject = rootObject;
continue;
}
// if we're on the last segment, the
boolean segmentIsLastSegment = (segmentContext.getNext() == null);
if (segmentIsLastSegment) {
// detect field type from class name if exists
if (targetField.getFieldType() == null && targetFieldClassName != null && (targetField instanceof JavaField)) {
FieldType fieldTypeFromClass = conversionService.fieldTypeFromClass(targetFieldClassName);
targetField.setFieldType(fieldTypeFromClass);
}
if (FieldType.COMPLEX.equals(targetField.getFieldType())) {
segmentIsComplexSegment = true;
} else {
segmentIsComplexSegment = false;
}
if (targetField instanceof JavaEnumField) {
segmentIsComplexSegment = false;
}
}
if (LOG.isDebugEnabled()) {
if (segmentIsComplexSegment) {
LOG.debug("Now processing complex segment: " + segmentContext);
} else if (targetField instanceof JavaEnumField) {
LOG.debug("Now processing field enum value segment: " + segmentContext);
} else {
LOG.debug("Now processing field value segment: " + segmentContext);
}
}
if (segmentIsComplexSegment) {
// processing parent object
Object childObject = findChildObject(targetField, segmentContext, parentObject);
if (childObject == null) {
childObject = createParentObject(targetField, parentObject, segmentContext);
}
parentObject = childObject;
} else {
// processing field value
if (AtlasPath.isCollectionSegment(segmentContext.getSegment())) {
parentObject = findOrCreateOrExpandParentCollectionObject(targetField, parentObject, segmentContext);
}
Object value = converter.convert(session, lookupTable, sourceField, parentObject, targetField);
addChildObject(targetField, segmentContext, parentObject, value);
}
}
} catch (Throwable t) {
if (LOG.isDebugEnabled()) {
LOG.debug("Error occured while writing field: " + targetField.getPath(), t);
}
if (t instanceof AtlasException) {
throw (AtlasException) t;
}
throw new AtlasException(t);
}
}
Aggregations