Search in sources :

Example 21 with AtlasPath

use of io.atlasmap.core.AtlasPath in project atlasmap by atlasmap.

the class KafkaConnectFieldReaderTest method createFc0Field.

private FieldGroup createFc0Field(AtlasPath parentPath) {
    FieldGroup fc0Field = new FieldGroup();
    AtlasPath path = parentPath.clone().appendField("fc0");
    fc0Field.setPath(path.toString());
    fc0Field.setFieldType(FieldType.COMPLEX);
    fc0Field.getField().add(createF0Field(path));
    return fc0Field;
}
Also used : FieldGroup(io.atlasmap.v2.FieldGroup) AtlasPath(io.atlasmap.core.AtlasPath)

Example 22 with AtlasPath

use of io.atlasmap.core.AtlasPath 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;
}
Also used : FieldGroup(io.atlasmap.v2.FieldGroup) ArrayList(java.util.ArrayList) JsonNode(com.fasterxml.jackson.databind.JsonNode) AtlasException(io.atlasmap.api.AtlasException) JsonEnumField(io.atlasmap.json.v2.JsonEnumField) JsonEnumField(io.atlasmap.json.v2.JsonEnumField) Field(io.atlasmap.v2.Field) JsonField(io.atlasmap.json.v2.JsonField) SegmentContext(io.atlasmap.core.AtlasPath.SegmentContext) JsonField(io.atlasmap.json.v2.JsonField) AtlasPath(io.atlasmap.core.AtlasPath)

Example 23 with AtlasPath

use of io.atlasmap.core.AtlasPath 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;
    }
}
Also used : JsonEnumField(io.atlasmap.json.v2.JsonEnumField) Field(io.atlasmap.v2.Field) JsonField(io.atlasmap.json.v2.JsonField) FieldGroup(io.atlasmap.v2.FieldGroup) AtlasPath(io.atlasmap.core.AtlasPath)

Example 24 with AtlasPath

use of io.atlasmap.core.AtlasPath 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());
    }
}
Also used : Field(io.atlasmap.v2.Field) JavaEnumField(io.atlasmap.java.v2.JavaEnumField) JavaField(io.atlasmap.java.v2.JavaField) JavaEnumField(io.atlasmap.java.v2.JavaEnumField) JavaField(io.atlasmap.java.v2.JavaField) FieldGroup(io.atlasmap.v2.FieldGroup) JavaFieldWriter(io.atlasmap.java.core.JavaFieldWriter) AtlasPath(io.atlasmap.core.AtlasPath)

Example 25 with AtlasPath

use of io.atlasmap.core.AtlasPath in project atlasmap by atlasmap.

the class CsvFieldReader method readFields.

private Field readFields(CsvField field) throws AtlasException {
    List<Field> fields = new ArrayList<>();
    CsvField csvField = field;
    CSVFormat csvFormat = csvConfig.newCsvFormat();
    try {
        document.mark(Integer.MAX_VALUE);
        CSVParser parser = csvFormat.parse(new InputStreamReader(document));
        AtlasPath atlasPath = new AtlasPath(csvField.getPath());
        int i = 0;
        Integer fieldIndex = atlasPath.getRootSegment().getCollectionIndex();
        if (fieldIndex != null) {
            for (CSVRecord record : parser) {
                if (i == fieldIndex) {
                    CsvField newField = CsvField.cloneOf(csvField);
                    // do not copy over index if set
                    newField.setIndex(null);
                    String value;
                    if (csvField.getColumn() != null) {
                        value = record.get(csvField.getColumn());
                    } else {
                        value = record.get(csvField.getName());
                    }
                    newField.setValue(value);
                    fields.add(newField);
                    break;
                }
                i++;
            }
        } else {
            for (CSVRecord record : parser) {
                CsvField collectionField = CsvField.cloneOf(csvField);
                // do not copy over index if set
                collectionField.setIndex(null);
                String value;
                if (csvField.getColumn() != null) {
                    value = record.get(csvField.getColumn());
                } else {
                    value = record.get(csvField.getName());
                }
                collectionField.setValue(value);
                AtlasPath collectionFieldPath = new AtlasPath(collectionField.getPath());
                collectionFieldPath.setCollectionIndex(0, i);
                collectionField.setPath(collectionFieldPath.toString());
                fields.add(collectionField);
                i++;
            }
        }
        document.reset();
    } catch (IOException e) {
        throw new AtlasException(e);
    }
    if (fields.size() == 1) {
        return fields.get(0);
    } else {
        FieldGroup fieldGroup = AtlasModelFactory.createFieldGroupFrom(field, true);
        fieldGroup.getField().addAll(fields);
        return fieldGroup;
    }
}
Also used : InputStreamReader(java.io.InputStreamReader) FieldGroup(io.atlasmap.v2.FieldGroup) ArrayList(java.util.ArrayList) IOException(java.io.IOException) AtlasException(io.atlasmap.api.AtlasException) CsvField(io.atlasmap.csv.v2.CsvField) Field(io.atlasmap.v2.Field) CsvField(io.atlasmap.csv.v2.CsvField) CSVParser(org.apache.commons.csv.CSVParser) AtlasPath(io.atlasmap.core.AtlasPath) CSVFormat(org.apache.commons.csv.CSVFormat) CSVRecord(org.apache.commons.csv.CSVRecord)

Aggregations

AtlasPath (io.atlasmap.core.AtlasPath)49 Field (io.atlasmap.v2.Field)27 FieldGroup (io.atlasmap.v2.FieldGroup)26 AtlasException (io.atlasmap.api.AtlasException)17 SegmentContext (io.atlasmap.core.AtlasPath.SegmentContext)14 JavaField (io.atlasmap.java.v2.JavaField)12 ArrayList (java.util.ArrayList)12 JavaEnumField (io.atlasmap.java.v2.JavaEnumField)11 KafkaConnectField (io.atlasmap.kafkaconnect.v2.KafkaConnectField)11 JsonField (io.atlasmap.json.v2.JsonField)5 JsonNode (com.fasterxml.jackson.databind.JsonNode)4 JsonEnumField (io.atlasmap.json.v2.JsonEnumField)4 Method (java.lang.reflect.Method)4 List (java.util.List)4 Test (org.junit.Test)4 SourceAddress (io.atlasmap.java.test.SourceAddress)3 SourceOrder (io.atlasmap.java.test.SourceOrder)3 KafkaConnectEnumField (io.atlasmap.kafkaconnect.v2.KafkaConnectEnumField)3 AtlasInternalSession (io.atlasmap.spi.AtlasInternalSession)3 Head (io.atlasmap.spi.AtlasInternalSession.Head)3