Search in sources :

Example 1 with XmlSegmentContext

use of io.atlasmap.xml.core.XmlPath.XmlSegmentContext in project atlasmap by atlasmap.

the class XmlFieldWriter method write.

@Override
public void write(AtlasInternalSession session) throws AtlasException {
    Field targetField = session.head().getTargetField();
    if (targetField == null) {
        throw new AtlasException(new IllegalArgumentException("Argument 'field' cannot be null"));
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("Now processing field path={} type={} value={}", targetField.getPath(), targetField.getFieldType(), targetField.getValue());
    }
    XmlPath path = new XmlPath(targetField.getPath());
    XmlSegmentContext lastSegment = path.getLastSegment();
    Element parentNode = null;
    XmlSegmentContext parentSegment = null;
    for (XmlSegmentContext segment : path.getXmlSegments(false)) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Now processing segment: {}", segment);
            LOG.debug("Parent element is currently: {}", xmlHelper.writeDocumentToString(true, parentNode));
        }
        if (parentNode == null) {
            // processing root node
            parentNode = document.getDocumentElement();
            if (parentNode == null) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Creating root element with name: {}", segment.getName());
                }
                // no root node exists yet, create root node with this segment name;
                Element rootNode = createElement(segment);
                addNamespacesToElement(rootNode, namespaces);
                document.appendChild(rootNode);
                parentNode = rootNode;
            } else if (!(parentNode.getNodeName().equals(segment.getQName()))) {
                // make sure root element's name matches.
                throw new AtlasException(String.format("Root element name '%s' does not match expected name '%s' from path: %s", parentNode.getNodeName(), segment.getName(), targetField.getPath()));
            }
            parentSegment = segment;
        } else {
            if (LOG.isDebugEnabled()) {
                if (segment.equals(lastSegment)) {
                    LOG.debug("Now processing field value segment: {}", segment);
                } else {
                    LOG.debug("Now processing parent segment: {}", segment);
                }
            }
            if (segment.equals(lastSegment) && targetField.getValue() == null) {
                break;
            }
            if (!segment.isAttribute()) {
                // if current segment of path isn't attribute, it refers to a child element,
                // find it or create it..
                Element childNode = getChildNode(parentNode, parentSegment, segment);
                if (childNode == null) {
                    childNode = createParentNode(parentNode, parentSegment, segment);
                }
                if (childNode == null) {
                    return;
                }
                parentNode = childNode;
                parentSegment = segment;
            }
            if (segment.equals(lastSegment)) {
                writeValue(parentNode, segment, targetField);
            }
        }
    }
}
Also used : Field(io.atlasmap.v2.Field) Element(org.w3c.dom.Element) AtlasException(io.atlasmap.api.AtlasException) XmlSegmentContext(io.atlasmap.xml.core.XmlPath.XmlSegmentContext)

Example 2 with XmlSegmentContext

use of io.atlasmap.xml.core.XmlPath.XmlSegmentContext in project atlasmap by atlasmap.

the class XmlFieldReader method getFieldsForPath.

private List<Field> getFieldsForPath(AtlasInternalSession session, Optional<XmlNamespaces> xmlNamespaces, Element node, Field field, XmlPath path, int depth) throws AtlasException {
    List<Field> fields = new ArrayList<>();
    List<XmlSegmentContext> segments = path.getXmlSegments(false);
    if (segments.size() < depth) {
        throw new AtlasException(String.format("depth '%s' exceeds segment size '%s'", depth, segments.size()));
    }
    if (segments.size() == depth) {
        if (!(field instanceof XmlEnumField) && field.getFieldType() == FieldType.COMPLEX) {
            FieldGroup group = (FieldGroup) field;
            populateChildFields(session, xmlNamespaces, node, group, path);
            fields.add(group);
        } else {
            XmlField xmlField = new XmlField();
            AtlasXmlModelFactory.copyField(field, xmlField, true);
            if (field instanceof XmlEnumField && xmlField.getFieldType() == FieldType.COMPLEX) {
                // enum has COMPLEX by default
                xmlField.setFieldType(FieldType.STRING);
            }
            copyValue(session, xmlNamespaces, segments.get(depth - 1), node, xmlField);
            // reset index for subfields
            xmlField.setIndex(null);
            fields.add(xmlField);
        }
        return fields;
    }
    // segments.size() > depth
    XmlSegmentContext segment = segments.get(depth);
    if (LOG.isDebugEnabled()) {
        LOG.debug("Now processing segment: " + segment.getName());
    }
    if (depth == 0) {
        if (segment.getName().startsWith(XmlIOHelper.getNodeNameWithoutNamespaceAlias(node))) {
            Optional<String> rootNamespace = Optional.empty();
            if (segment.getNamespace() != null) {
                rootNamespace = getNamespace(xmlNamespaces, segment.getNamespace());
            }
            if (!rootNamespace.isPresent() || rootNamespace.get().equals(node.getNamespaceURI())) {
                // "/XOA/contact<>/firstName", skip.
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Skipping root segment: " + segment);
                }
                if (segments.size() > 1) {
                    depth = 1;
                    segment = segments.get(depth);
                }
            }
        }
    }
    if (segment.isAttribute() && segments.size() == depth + 1) {
        // if last segment is attribute
        List<Field> attrFields = getFieldsForPath(session, xmlNamespaces, node, field, path, depth + 1);
        fields.addAll(attrFields);
        return fields;
    }
    String fieldName = segment.getName();
    String fieldNamespace = segment.getNamespace();
    Optional<String> namespace = getNamespace(xmlNamespaces, fieldNamespace);
    List<Element> children = XmlIOHelper.getChildrenWithNameStripAlias(fieldName, namespace, node);
    if (children == null || children.isEmpty()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Skipping source value set, couldn't find children with name '" + fieldName + "', for segment: " + segment);
        }
        return fields;
    }
    if (segment.getCollectionType() == CollectionType.NONE) {
        List<Field> childFields = getFieldsForPath(session, xmlNamespaces, children.get(0), field, path, depth + 1);
        fields.addAll(childFields);
        return fields;
    }
    // collection
    Integer index = segment.getCollectionIndex();
    if (index != null) {
        if (index < children.size()) {
            List<Field> arrayFields = getFieldsForPath(session, xmlNamespaces, children.get(index), field, path, depth + 1);
            fields.addAll(arrayFields);
        } else if (LOG.isDebugEnabled()) {
            LOG.debug("Skipping source value set, children list can't fit index " + index + ", children list size: " + children.size());
        }
    } else {
        // if index not included, iterate over all
        for (int i = 0; i < children.size(); i++) {
            Field itemField;
            if (field instanceof FieldGroup) {
                itemField = AtlasXmlModelFactory.cloneFieldGroup((FieldGroup) field);
                AtlasPath.setCollectionIndexRecursively((FieldGroup) itemField, depth + 1, i);
            } else {
                itemField = AtlasXmlModelFactory.cloneField((XmlField) field, false);
                AtlasPath itemPath = new AtlasPath(field.getPath());
                itemPath.setCollectionIndex(depth + 1, i);
                itemField.setPath(itemPath.toString());
            }
            List<Field> arrayFields = getFieldsForPath(session, xmlNamespaces, children.get(i), itemField, new XmlPath(itemField.getPath()), depth + 1);
            fields.addAll(arrayFields);
        }
    }
    return fields;
}
Also used : FieldGroup(io.atlasmap.v2.FieldGroup) XmlEnumField(io.atlasmap.xml.v2.XmlEnumField) XmlField(io.atlasmap.xml.v2.XmlField) Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) AtlasException(io.atlasmap.api.AtlasException) XmlSegmentContext(io.atlasmap.xml.core.XmlPath.XmlSegmentContext) Field(io.atlasmap.v2.Field) XmlField(io.atlasmap.xml.v2.XmlField) XmlEnumField(io.atlasmap.xml.v2.XmlEnumField) AtlasPath(io.atlasmap.core.AtlasPath)

Aggregations

AtlasException (io.atlasmap.api.AtlasException)2 Field (io.atlasmap.v2.Field)2 XmlSegmentContext (io.atlasmap.xml.core.XmlPath.XmlSegmentContext)2 Element (org.w3c.dom.Element)2 AtlasPath (io.atlasmap.core.AtlasPath)1 FieldGroup (io.atlasmap.v2.FieldGroup)1 XmlEnumField (io.atlasmap.xml.v2.XmlEnumField)1 XmlField (io.atlasmap.xml.v2.XmlField)1 ArrayList (java.util.ArrayList)1