Search in sources :

Example 41 with Collection

use of io.atlasmap.v2.Collection in project atlasmap by atlasmap.

the class DefaultAtlasFieldActionService method processOneToMany.

private Field processOneToMany(Action action, ActionProcessor processor, FieldType sourceType, Field field) throws AtlasException {
    Object value = field.getValue();
    if (value != null && isAssignableFieldType(processor.getActionDetail().getSourceType(), sourceType)) {
        value = getConversionService().convertType(value, sourceType, processor.getActionDetail().getSourceType());
    }
    value = processor.process(action, value);
    FieldGroup answer = AtlasModelFactory.createFieldGroupFrom(field, false);
    AtlasPath path = new AtlasPath(answer.getPath() + AtlasPath.PATH_LIST_SUFFIX);
    answer.setPath(path.toString());
    answer.setCollectionType(CollectionType.LIST);
    answer.setFieldType(processor.getActionDetail().getTargetType());
    List<Object> values;
    if (value != null && value.getClass().isArray()) {
        values = Arrays.asList((Object[]) value);
    } else if ((value instanceof Collection) && !(value instanceof List)) {
        values = Arrays.asList(((Collection<?>) value).toArray());
    } else {
        values = new LinkedList<>();
        if (value != null) {
            values.add(value);
        }
    }
    for (int i = 0; i < values.size(); i++) {
        Field subField = AtlasModelFactory.cloneFieldToSimpleField(answer);
        AtlasPath subPath = new AtlasPath(answer.getPath());
        subPath.setVacantCollectionIndex(i);
        subField.setPath(subPath.toString());
        subField.setCollectionType(CollectionType.NONE);
        subField.setIndex(null);
        subField.setValue(values.get(i));
        answer.getField().add(subField);
    }
    return answer;
}
Also used : Field(io.atlasmap.v2.Field) SimpleField(io.atlasmap.v2.SimpleField) FieldGroup(io.atlasmap.v2.FieldGroup) Collection(java.util.Collection) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) LinkedList(java.util.LinkedList)

Example 42 with Collection

use of io.atlasmap.v2.Collection in project atlasmap by atlasmap.

the class DefaultAtlasPreviewContext method processPreview.

/**
 * Process single mapping entry in preview mode. Since modules don't participate
 * in preview mode, any document format specific function won't be applied.
 *
 * @param mapping A @link{Mapping} entry to process
 */
@Override
public Audits processPreview(Mapping mapping) throws AtlasException {
    DefaultAtlasSession session = new DefaultAtlasSession(this);
    this.originalMapping = mapping;
    Mapping cloned;
    try {
        byte[] serialized = jsonMapper.writeValueAsBytes(mapping);
        cloned = jsonMapper.readValue(serialized, Mapping.class);
    } catch (Exception e) {
        throw new AtlasException(e);
    }
    session.head().setMapping(cloned);
    MappingType mappingType = cloned.getMappingType();
    String expression = cloned.getExpression();
    FieldGroup sourceFieldGroup = cloned.getInputFieldGroup();
    List<Field> sourceFields = cloned.getInputField();
    List<Field> targetFields = cloned.getOutputField();
    targetFields.forEach(tf -> tf.setValue(null));
    if ((sourceFieldGroup == null && sourceFields.isEmpty()) || targetFields.isEmpty()) {
        return session.getAudits();
    }
    if (sourceFieldGroup != null) {
        sourceFields = sourceFieldGroup.getField();
    }
    for (Field sf : sourceFields) {
        if (sf.getFieldType() == null || sf.getValue() == null) {
            continue;
        }
        if (sf.getValue() instanceof String && ((String) sf.getValue()).isEmpty()) {
            continue;
        }
        if (!restoreSourceFieldType(session, sf)) {
            return session.getAudits();
        }
    }
    processSourceFieldMapping(session);
    if (session.hasErrors()) {
        return session.getAudits();
    }
    Field sourceField = session.head().getSourceField();
    Field targetField;
    if (mappingType == null || mappingType == MappingType.MAP) {
        sourceFieldGroup = sourceField instanceof FieldGroup ? (FieldGroup) sourceField : null;
        for (int i = 0; i < targetFields.size(); i++) {
            targetField = targetFields.get(i);
            session.head().setTargetField(targetField);
            if (sourceFieldGroup != null) {
                if (sourceFieldGroup.getField().size() == 0) {
                    AtlasUtil.addAudit(session, targetField, String.format("Skipping empty source group field '%s:%s'", sourceField.getDocId(), sourceField.getPath()), AuditStatus.INFO, null);
                    continue;
                }
                Integer index = targetField.getIndex();
                AtlasPath targetPath = new AtlasPath(targetField.getPath());
                if (targetPath.hasCollection() && !targetPath.isIndexedCollection()) {
                    if (targetFields.size() > 1) {
                        AtlasUtil.addAudit(session, targetField, "It's not yet supported to have a collection field as a part of multiple target fields in a same mapping", AuditStatus.ERROR, null);
                        session.getAudits().getAudit().addAll(session.head().getAudits());
                        return session.getAudits();
                    }
                    if (index != null) {
                        LOG.warn("Field index '{}' is detected on target field '{}:{}' while there's only one target field, ignoring", index, targetField.getDocId(), targetField.getPath());
                        targetField.setIndex(null);
                    }
                    FieldGroup targetFieldGroup = targetField instanceof FieldGroup ? (FieldGroup) targetField : AtlasModelFactory.createFieldGroupFrom(targetField, true);
                    targetFields.set(i, targetFieldGroup);
                    Field previousTargetField = null;
                    for (Field subSourceField : sourceFieldGroup.getField()) {
                        Field subTargetField = AtlasModelFactory.cloneFieldToSimpleField(targetFieldGroup);
                        targetFieldGroup.getField().add(subTargetField);
                        collectionHelper.copyCollectionIndexes(sourceFieldGroup, subSourceField, subTargetField, previousTargetField);
                        previousTargetField = subTargetField;
                        if (!convertSourceToTarget(session, subSourceField, subTargetField)) {
                            session.getAudits().getAudit().addAll(session.head().getAudits());
                            return session.getAudits();
                        }
                        ;
                        Field processed = subTargetField;
                        if (expression == null || expression.isEmpty()) {
                            processed = applyFieldActions(session, subTargetField);
                        }
                        subTargetField.setValue(processed.getValue());
                    }
                    continue;
                } else if (index == null) {
                    session.head().setSourceField(sourceFieldGroup.getField().get(sourceFieldGroup.getField().size() - 1));
                } else {
                    if (sourceFieldGroup.getField().size() > index) {
                        session.head().setSourceField(sourceFieldGroup.getField().get(index));
                    } else {
                        AtlasUtil.addAudit(session, targetField, String.format("The number of source fields '%s' is fewer than expected via target field index '%s'", sourceFieldGroup.getField().size(), targetField.getIndex()), AuditStatus.WARN, null);
                        continue;
                    }
                }
            }
            if (session.hasErrors()) {
                session.getAudits().getAudit().addAll(session.head().getAudits());
                return session.getAudits();
            }
            if (!convertSourceToTarget(session, session.head().getSourceField(), targetField)) {
                session.getAudits().getAudit().addAll(session.head().getAudits());
                return session.getAudits();
            }
            Field processed = targetField;
            if (expression == null || expression.isEmpty()) {
                processed = applyFieldActions(session, targetField);
            }
            targetField.setValue(processed.getValue());
        }
    } else if (mappingType == MappingType.COMBINE) {
        targetField = targetFields.get(0);
        Field combined = processCombineField(session, cloned, sourceFields, targetField);
        if (!convertSourceToTarget(session, combined, targetField)) {
            session.getAudits().getAudit().addAll(session.head().getAudits());
            return session.getAudits();
        }
        applyFieldActions(session, targetField);
    } else if (mappingType == MappingType.SEPARATE) {
        List<Field> separatedFields;
        try {
            separatedFields = processSeparateField(session, cloned, sourceField);
        } catch (AtlasException e) {
            AtlasUtil.addAudit(session, sourceField, String.format("Failed to separate field: %s", AtlasUtil.getChainedMessage(e)), AuditStatus.ERROR, null);
            if (LOG.isDebugEnabled()) {
                LOG.error("", e);
            }
            session.getAudits().getAudit().addAll(session.head().getAudits());
            return session.getAudits();
        }
        if (separatedFields == null) {
            session.getAudits().getAudit().addAll(session.head().getAudits());
            return session.getAudits();
        }
        for (Field f : targetFields) {
            targetField = f;
            if (targetField.getIndex() == null || targetField.getIndex() < 0) {
                AtlasUtil.addAudit(session, targetField, String.format("Separate requires zero or positive Index value to be set on targetField targetField.path=%s", targetField.getPath()), AuditStatus.WARN, null);
                continue;
            }
            if (separatedFields.size() <= targetField.getIndex()) {
                String errorMessage = String.format("Separate returned fewer segments count=%s when targetField.path=%s requested index=%s", separatedFields.size(), targetField.getPath(), targetField.getIndex());
                AtlasUtil.addAudit(session, targetField, errorMessage, AuditStatus.WARN, null);
                break;
            }
            if (!convertSourceToTarget(session, separatedFields.get(targetField.getIndex()), targetField)) {
                break;
            }
            applyFieldActions(session, targetField);
        }
    } else {
        AtlasUtil.addAudit(session, (String) null, String.format("Unsupported mappingType=%s detected", cloned.getMappingType()), AuditStatus.ERROR, null);
    }
    mapping.getOutputField().clear();
    mapping.getOutputField().addAll(cloned.getOutputField());
    session.getAudits().getAudit().addAll(session.head().getAudits());
    return session.getAudits();
}
Also used : MappingType(io.atlasmap.v2.MappingType) FieldGroup(io.atlasmap.v2.FieldGroup) Mapping(io.atlasmap.v2.Mapping) AtlasMapping(io.atlasmap.v2.AtlasMapping) AtlasException(io.atlasmap.api.AtlasException) AtlasException(io.atlasmap.api.AtlasException) AtlasConversionException(io.atlasmap.api.AtlasConversionException) SimpleField(io.atlasmap.v2.SimpleField) Field(io.atlasmap.v2.Field)

Example 43 with Collection

use of io.atlasmap.v2.Collection in project atlasmap by atlasmap.

the class JsonFieldWriter method write.

@Override
public void write(AtlasInternalSession session) throws AtlasException {
    Field targetField = session.head().getTargetField();
    if (targetField == null) {
        throw new AtlasException(new IllegalArgumentException("Argument 'jsonField' cannot be null"));
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("Field: " + AtlasModelFactory.toString(targetField));
        LOG.debug("Field type=" + targetField.getFieldType() + " path=" + targetField.getPath() + " v=" + targetField.getValue());
    }
    AtlasPath path = new AtlasPath(targetField.getPath());
    SegmentContext lastSegment = path.getLastSegment();
    if (this.rootNode == null) {
        if (path.hasCollectionRoot()) {
            this.rootNode = objectMapper.createArrayNode();
        } else {
            this.rootNode = objectMapper.createObjectNode();
        }
    }
    ContainerNode<?> parentNode = this.rootNode;
    SegmentContext parentSegment = null;
    for (SegmentContext segment : path.getSegments(true)) {
        if (!segment.equals(lastSegment)) {
            // this is a parent node.
            if (LOG.isDebugEnabled()) {
                LOG.debug("Now processing parent segment: " + segment);
            }
            JsonNode childNode;
            if (segment.isRoot()) {
                if (parentNode instanceof ArrayNode) {
                    // taking care of topmost collection
                    childNode = parentNode;
                } else {
                    parentSegment = segment;
                    continue;
                }
            } else {
                childNode = getChildNode(parentNode, parentSegment, segment);
            }
            if (childNode == null) {
                childNode = createParentNode(parentNode, parentSegment, segment);
            } else if (childNode instanceof ArrayNode) {
                Integer index = segment.getCollectionIndex();
                if (index == null) {
                    return;
                }
                ArrayNode arrayChild = (ArrayNode) childNode;
                if (arrayChild.size() < (index + 1)) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Object Array is too small, resizing to accomodate index: " + index + ", current array: " + arrayChild);
                    }
                    // index available
                    while (arrayChild.size() < (index + 1)) {
                        arrayChild.addObject();
                    }
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Object Array after resizing: " + arrayChild);
                    }
                }
                childNode = arrayChild.get(index);
            }
            if (childNode == null) {
                return;
            }
            parentNode = (ObjectNode) childNode;
            parentSegment = segment;
        } else {
            // this is the last segment of the path, write the value
            if (targetField.getFieldType() == FieldType.COMPLEX) {
                createParentNode(parentNode, parentSegment, segment);
                return;
            }
            if (LOG.isDebugEnabled()) {
                LOG.debug("Now processing field value segment: " + segment);
            }
            writeValue(parentNode, parentSegment, segment, targetField);
        }
    }
}
Also used : BigInteger(java.math.BigInteger) Field(io.atlasmap.v2.Field) SegmentContext(io.atlasmap.core.AtlasPath.SegmentContext) AtlasPath(io.atlasmap.core.AtlasPath) JsonNode(com.fasterxml.jackson.databind.JsonNode) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) AtlasException(io.atlasmap.api.AtlasException)

Aggregations

Field (io.atlasmap.v2.Field)25 FieldGroup (io.atlasmap.v2.FieldGroup)15 AtlasPath (io.atlasmap.core.AtlasPath)14 AtlasMapping (io.atlasmap.v2.AtlasMapping)14 AtlasException (io.atlasmap.api.AtlasException)11 ArrayList (java.util.ArrayList)10 Mapping (io.atlasmap.v2.Mapping)9 SegmentContext (io.atlasmap.core.AtlasPath.SegmentContext)8 Collection (io.atlasmap.v2.Collection)7 SimpleField (io.atlasmap.v2.SimpleField)7 List (java.util.List)7 Test (org.junit.jupiter.api.Test)7 JavaEnumField (io.atlasmap.java.v2.JavaEnumField)6 JavaField (io.atlasmap.java.v2.JavaField)6 LinkedList (java.util.LinkedList)6 AtlasContext (io.atlasmap.api.AtlasContext)5 AtlasSession (io.atlasmap.api.AtlasSession)5 ADMArchiveHandler (io.atlasmap.core.ADMArchiveHandler)5 ConstantField (io.atlasmap.v2.ConstantField)5 InputStream (java.io.InputStream)5