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);
}
}
}
}
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;
}
Aggregations